iOS Question [SOLVED] Problem with NSTimeZone

JackKirk

Well-Known Member
Licensed User
Hi,

I'm trying to work out how to change timezones with code like:
B4X:
#Region  Project Attributes
    #ApplicationLabel: B4i Example
    #Version: 1.0.0
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
    #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
    #Target: iPhone, iPad
    #ATSEnabled: True
    #MinVersion: 8
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
    Private xui As XUI
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)



    Dim no As NativeObject
    no.Initialize("NSTimeZone")
    Dim orig_timeZone As Object = no.RunMethod("defaultTimeZone", Null)

Log(orig_timeZone)
Log(DateTime.TimeZoneOffset)

    Dim no As NativeObject
    no.Initialize("NSTimeZone")
    no.RunMethod("setDefaultTimeZone:", Array(no.RunMethod("timeZoneWithName:", Array("GMT"))))

    Dim no As NativeObject
    no.Initialize("NSTimeZone")
    Dim orig_timeZone As Object = no.RunMethod("defaultTimeZone", Null)
   
Log(orig_timeZone)
Log(DateTime.TimeZoneOffset)      '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   
    Dim no As NativeObject
    no.Initialize("NSTimeZone")
    no.RunMethod("setDefaultTimeZone:", Array(no.RunMethod("systemTimeZone", Null)))
   
    Dim no As NativeObject
    no.Initialize("NSTimeZone")
    Dim orig_timeZone As Object = no.RunMethod("defaultTimeZone", Null)
   
Log(orig_timeZone)
Log(DateTime.TimeZoneOffset)
   
End Sub

The problem is this generates a log of:
Application_Start
Australia/Sydney (AEST) offset 36000
10
GMT (GMT) offset 0
10 <<<<<<<<<<<<<<<<<<<<<<<<<<<<
Australia/Sydney (AEST) offset 36000
10
Application_Active
Application_Inactive
I would have thought the line I have highlit with <<<<<<<<<<< would read "0"

Can anyone enlighten me?

Thanks...
 
Last edited:

JackKirk

Well-Known Member
Licensed User
Erel,

Daylight saving happened a couple of days ago and I'm back trying to sort this:

My last effort did not fix the problem.

I think I have a solution for B4J which is based on something you said at:

I am trying to develop a solution across B4J/A/i so I can incorporate it into my AWS S3 signature code at:

Any help appreciated...
 
Upvote 0

JackKirk

Well-Known Member
Licensed User
Why do you need to change the timezone?
If I change the DateTime.SetTimeZone my understanding is that the daylight saving data embedded in the apps timezone is lost - so if I subsequently go over a a daylight saving event the subsequent DateTime.Date and DateTime.Time calls will be wrong.

I assume this is so for B4i because it surely is for B4J.

I would appreciate some help here...
 
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
Keep date/time in UTC (similar DateTime.Now).

DateTime.Date / DateTime.Time convert to local time, which includes daylightSavingTimeOffset.
For example,
B4X:
    Log (DateTime.Date (DateTime.Now) & " " & DateTime.Time (DateTime.Now))
    Log (DateTime.Date (DateTime.Now - 1000 * 60 * 60 * 24 * 31) & " " & DateTime.Time (DateTime.Now - 1000 * 60 * 60 * 24 * 31))

Just now output is
04/08/2021 05:47:49
03/08/2021 06:47:49

The difference in one hour is due to daylightSavingTimeOffset (1 hour in March)
 
Upvote 0

JackKirk

Well-Known Member
Licensed User
I'm sorry but you still haven't answered my question. Why do you need to change the time zone??? Maybe there is a different, better way to do whatever you are trying to do.
Erel, I need to be able to generate the GMT/UTC/DateTime.Now with DateTime.DateFormat of "yyyyMMdd'T'HHmmss'Z'" for use in my AWS S3 signature generator code:
https://www.b4x.com/android/forum/t...re-calculator-b4x-works-on-b4a-b4i-b4j.81272/

I realize I can use something like:

Private oldtimezoneoffset as Double = DateTime.TimeZoneOffset
DateTime.SetTimeZone(0)
DateTime.DateFormat = "yyyyMMdd'T'HHmmss'Z'"
Private wrk_str as string = DateTime.Date(DateTime.Now)
DateTime.SetTimeZone(oldtimezoneoffset)

But my understanding is that after doing this the app's daylight saving info is lost so if the app is still alive over a subsequent daylight saving change event then DateTime.TimeZoneOffset will remain unchanged thus screwing any normal use of DateTime.Date.

The "understanding" above is based on my experience with B4J, is B4i different?

I would appreciate any help with this...

PS for the same reasons I need a fix for B4A:
https://www.b4x.com/android/forum/threads/problem-with-changing-time-zones.129458/
 
Last edited:
Upvote 0

Erel

Administrator
Staff member
Licensed User
Upvote 0

JackKirk

Well-Known Member
Licensed User
Now I can help you.
Erel, thanks for this - a neat solution to a nagging edge case.

I have tested it against B4J by isolating my PC, manually setting date/time to just before a daylight saving change event then observing results - worked perfectly.

When I get time I will check it against B4A/i - but may leave it until the next real DLS change event.

I will update my AWS S3 signature generator code:
https://www.b4x.com/android/forum/t...re-calculator-b4x-works-on-b4a-b4i-b4j.81272/

Thanks again...
 
Upvote 0
Top