B4J Question Day light saving with long running B4J apps

JackKirk

Well-Known Member
Licensed User
I have a number of B4J apps running on AWS EC2 instances.

These apps are continuously running.

Even though the EC2 instances (effectively just PCs running Windows 10) are physically located in Oregon USA I have their timezone set to:

(UTC +10.00) Canberra, Melbourne, Sydney

with automatic adjustment for daylight saving turned on.

Reason being that the apps interact with events happening in Sydney.

Yesterday (Sunday) daylight saving kicked in in Sydney.

The EC2 instances adjusted automatically (as evidenced by the date/time display in bottom right of screen).

The B4J apps did not.

I have found if the B4J apps are stopped/started they adjust.

Is this expected behaviour?

Is there any simple way to automatically get them to adjust without having to remember to stop/start them at every daylight saving change event?

Thanks in anticipation...
 

Erel

Administrator
Staff member
Licensed User
The problem happens because you explicitly set the timezone based on a specific offset.

The solution is to set it with a timezone object:
B4X:
Dim jo As JavaObject
jo.InitializeStatic("anywheresoftware.b4a.keywords.DateTime")
Dim TimeZone As JavaObject
TimeZone.InitializeStatic("java.util.TimeZone")
TimeZone = TimeZone.RunMethod("getTimeZone", Array("Australia/Sydney"))
jo.RunMethod("setTimeZoneInternal", Array(TimeZone))
Log(jo.RunMethodJO("getInst", Null).GetField("timeZone"))
'test
Log(DateTime.GetTimeZoneOffsetAt(DateTime.DateParse("08/01/2010")))
Log(DateTime.GetTimeZoneOffsetAt(DateTime.DateParse("01/01/2010")))
However it will only work in the next update to B4J as there are several fields that aren't exposed in the current version.

Note that if it is a server solution then you need to set the timezone in each handler instance. You can call a sub in the main module to do it.
 

JackKirk

Well-Known Member
Licensed User
Erel,

Not sure I understand your response...

The problem happens because you explicitly set the timezone based on a specific offset.
I have not knowingly set the timezone - aside from in the AWS EC2 instances date/time settings.

Am I right in thinking that I have "explicitly set the timezone based on a specific offset" by just using the B4J DateTime methods?

However it will only work in the next update to B4J as there are several fields that aren't exposed in the current version.
Which begs the question when will this be available?

Note that if it is a server solution then you need to set the timezone in each handler instance
Am I right in interpreting this to mean that I should put your suggested code in each B4J app running in the AWS EC2 instances?

Thanks...
 

Erel

Administrator
Staff member
Licensed User
Am I right in thinking that I have "explicitly set the timezone based on a specific offset" by just using the B4J DateTime methods?
No. I mistakenly assumed that you called DateTime.SetTimeZone. I guess that it is not the case, right?

What is the output of these two lines:
B4X:
Log(DateTime.GetTimeZoneOffsetAt(DateTime.DateParse("08/01/2010")))
Log(DateTime.GetTimeZoneOffsetAt(DateTime.DateParse("01/01/2010")))
 

JackKirk

Well-Known Member
Licensed User
Log(DateTime.GetTimeZoneOffsetAt(DateTime.DateParse("08/01/2010")))
Log(DateTime.GetTimeZoneOffsetAt(DateTime.DateParse("01/01/2010")))
Waiting for debugger to connect...
Program started.
10
11
This is a simple bit of code just incorporating the 2 log statements and not including code in next post - on an AWS EC2 instance.
 
Last edited:

JackKirk

Well-Known Member
Licensed User
No. I mistakenly assumed that you called DateTime.SetTimeZone. I guess that it is not the case, right?
Initially I thought the answer to this was "correct" but then I dug a lot deeper...

All the AWS EC2 B4J apps are mucking around with various AWS services such as S3.

In the classes I have developed to do this (documented elsewhere in the forums) I have:
B4X:
'************************************************************************************
'
'This procedure creates a timeStampISO8601Format as per:
'    http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html
'    Task 2: Create a String to Sign
'
'Input parameters are:
'
'       None
'
'Returns:
'
'       timeStampISO8601Format
'
'Notes on this procedure:
'
'       o None
'
'************************************************************************************
Private Sub timeStampISO8601Format As String
 
    DateTime.DateFormat = "yyyyMMdd'T'HHmmss'Z'"

    Private wrk_timezone As Double = DateTime.TimeZoneOffset
    DateTime.SetTimeZone(0)
    Private wrk_str As String = DateTime.Date(AWS_S3_Local_DateTime)
    DateTime.SetTimeZone(wrk_timezone)
 
    Return wrk_str

End Sub
But I don't think it affects anything - it reads current TimeZoneOffset, does some fiddles then resets it to original.

Or does it???
 
Last edited:

JackKirk

Well-Known Member
Licensed User
Erel,

Note that you can use DateUtils.SetDateAndTime2 instead of changing the time zone.
I cannot for the life of me work out how to use DateUtils.SetDateAndTime2 to produce the same effect as this code and avoid changing the time zone:

B4X:
Private Sub timeStampISO8601Format As String
 
    DateTime.DateFormat = "yyyyMMdd'T'HHmmss'Z'"

    Private wrk_timezone As Double = DateTime.TimeZoneOffset
    DateTime.SetTimeZone(0)
    Private wrk_str As String = DateTime.Date(AWS_S3_Local_DateTime)
    DateTime.SetTimeZone(wrk_timezone)
 
    Return wrk_str

End Sub
AWS_S3_Local_DateTime is a long.

Any guidance appreciated...
 

JackKirk

Well-Known Member
Licensed User
Would this work?
B4X:
Private Sub timeStampISO8601Format As String
 
    DateTime.DateFormat = "yyyyMMdd'T'HHmmss'Z'"

    Return DateTime.Date(AWS_S3_Local_DateTime - DateTime.TimeZoneOffset * DateTime.TicksPerHour)

End Sub
Sorry for asking but I can't easily test this for 6 months...
 

JackKirk

Well-Known Member
Licensed User
Erel,

My code at post #9 I think generates the same result as at post #8 but does not do any DateTime.SetTimeZone

If my understanding of this thread is correct this should mean that the surrounding app will not have any daylight saving change problems - if it runs over a daylight saving change.

The timeStampISO8601Format subroutine is part of the AWS S3 class I put on the forum some time ago, refer:

https://www.b4x.com/android/forum/t...lator-b4x-works-on-b4a-b4i-b4j.81272/#content

The user of the class supplies AWS_S3_Local_DateTime, typically as DateTime.Now

-----------------------------------

What I was after was just your confirmation of the correctness of the first 2 paragraphs of this post - as I have to wait 6 months to test it at the next daylight saving change event.

Thanks...
 

JackKirk

Well-Known Member
Licensed User
The timezone will change automatically together with the machine timezone as long as you never call SetTimeZone.
Thanks Erel - I did not find this spelt out any where on the forums - its a reasonably extreme edge case but probably important for a lot of long running B4J apps.

If I manage to test it over the next daylight saving change I will add another post.

Then I will update the AWS S3 class accordingly.
 
Last edited:
Top