DateTime bug?

jota

Active Member
Licensed User
Longtime User
By using the following code gives the resulting log deviation of 1 hour, is a failure or I interpret something wrong. thanks

Sub Globals
Dim TIMER1 As Timer
End Sub

Sub Activity_Create(FirstTime As Boolean)
TIMER1.Initialize("timer1",1000)
TIMER1.Enabled = True
End Sub
Sub timer1_Tick
Dim t,d As Long
d = DateTime.DateParse(DateTime.Date(DateTime.Now))
t = DateTime.TimeParse(DateTime.Time(DateTime.Now))
Log("-----------------------------")
Log(DateTime.date(DateTime.Now) & "-" & DateTime.Time(DateTime.Now))
Log(DateTime.Date(d) & " - " & DateTime.Time(t))
Log("-----------------------------")
End Sub

Log:
-----------------------------
04/22/2012-14:07:47
04/22/2012 - 15:07:47
-----------------------------
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Which one is correct?
Can you run the following code and post the result:
B4X:
Log("-----------------------------")
Log(DateTime.date(DateTime.Now) & "-" & DateTime.Time(DateTime.Now))
Log(DateTime.Date(d) & " - " & DateTime.Time(t))
Log(DateTime.Time(DateTime.Now))
Log(DateTime.GetTimeZoneOffsetAt(DateTime.Now))
Log("-----------------------------")
 

jota

Active Member
Licensed User
Longtime User
the correct line is: 04/22/2012-14: 07:47

and the result of your code:
-----------------------------
04/22/2012-16:47:24
04/22/2012 - 17:47:24
16:47:24
2
-----------------------------

thanks
 

jota

Active Member
Licensed User
Longtime User
Correct -> Log(DateTime.date(DateTime.Now) & "-" & DateTime.Time(DateTime.Now))

1 hour more incorrect ->Log(DateTime.Date(d) & " - " & DateTime.Time(t))

:)

Are you sure that your device settings are correct?

In your phone the code, run ok?



sorry, my English is confusing I owe to Google translator
 
Last edited:

jota

Active Member
Licensed User
Longtime User
The problem seems to come from the times zones.

If I put the phone configuration time zone = 0, the code works fine, but if I put a different time zone returns erroneous results.

TimeParse includes time zones?. thanks
 

jota

Active Member
Licensed User
Longtime User
It is probably related to DST (Daylight saving time). What is your device time zone setting?

my time zone is +1 Spain and automatic configuration think google gets +2 for summer time.
 

jota

Active Member
Licensed User
Longtime User
the problem is definitely android. Adding DateTime.SetTimeZone (1) the code works correctly. Is there any way of knowing the true time zone of the phone?
 

jota

Active Member
Licensed User
Longtime User
This is the code that works for me.

Sub Globals
Dim TIMER1 As Timer
End Sub

Sub Activity_Create(FirstTime As Boolean)
TIMER1.Initialize("timer1",1000)
TIMER1.Enabled = True
End Sub
Sub timer1_Tick
Dim t,d As Long
DateTime.SetTimeZone(DateTime.GetTimeZoneOffsetAt(DateTime.Now)) '< SOLUTION >
d = DateTime.DateParse(DateTime.Date(DateTime.Now))
t = DateTime.TimeParse(DateTime.Time(DateTime.Now))
Log("-----------------------------")
Log(DateTime.date(DateTime.Now) & "-" & DateTime.Time(DateTime.Now))
Log(DateTime.Date(d) & " - " & DateTime.Time(t))
Log("-----------------------------")
End Sub


Thanks for the help:sign0060:
 
Last edited:

Ianmac

Member
Licensed User
Longtime User
Hi all

I have been away from programming for some months but have just taken up B4A again and my first app involves DateTime.
I am surprised that setting a datetime variable to 0 returns an output of 01:00 i.e. 1 hour, I am subtracting times by the way.
I am on BST but can't get my head around the fact that a time of 0 returns such an error. As yet I have not seen an understandable explanation, can anyone help? :confused:
 

Roger Garstang

Well-Known Member
Licensed User
Longtime User
This thread is confusing. So, why did-
B4X:
DateTime.SetTimeZone(DateTime.GetTimeZoneOffsetAt( DateTime.Now))
fix this?

I've been playing with Date and Time Dialogs the last couple days. I've been setting date/time values by ticks along with getting current date/time and it seems to be returning the correct values so far without setting the timezone. It seemed to me that the class was already setting the current timezone without me needing to do it. So, is it really just setting the Timezone without DST, and we have to set it ourselves according to current date like above to get the DST shift applied?

The docs aren't very clear as to how the timezones and DST work within the class. I would assume ticks are stored in GMT/UTC without any DST shifts...would that be a correct assumption? Then when you get a date string it converts it according to your Timezone setting and that is what shows right?
 

Roger Garstang

Well-Known Member
Licensed User
Longtime User
Ok, a couple things still confuse me, and I think there is still something wrong with GetTimeZoneOffsetAt.

1. TimezoneOffset is a Double, GetTimeZoneOffsetAt returns a Double, SetTimezone wants an Int. As far as I know offsets and DST shifts are all Ints, so where do the Doubles come in? TimezoneOffset is also Read Only, so the only way to set it is with an Int.

2. I agree Ticks are stored as GMT/UTC and the default TimezoneOffset appears to be the same as what GetTimeZoneOffsetAt returns which is the Shift + DST. This is where things start to differ though...how is GetTimeZoneOffsetAt figuring its value? It appears to be just going directly off of the TimezoneOffset number. I see nowhere to specify a Timezone for areas like Arizona and others that don't perform DST. With this in mind I was expecting GetTimeZoneOffsetAt to read from the Device Timezone instead of the Application offset in DateTime, but it is not. (I also tried setting my Timezone in Android to Arizona and the Datetime object performs an invalid DST shift when I change the date on the device- Both the default TimezoneOffset and what GetTimeZoneOffsetAt returns)

I have an application where I want to store GMT Time in the database, so I do a DateTime.SetTimeZone(0) before writing to text to the database (This goes into MySql later and ticks have limitations similar to Y2K until everything goes 64bit, so I don't store ticks). I then do a DateTime.SetTimeZone(DateTime.GetTimeZoneOffsetAt(DateTime.Now)) that I had expected to reset it back to the correct offset, but it sets it to 0 like it is getting the offset of GMT and also doesn't include DST.

This may work for some areas, but in reality there is no true way of returning the DateTime object's Timezone to the device's after it is changed and it is calculating DST shifts incorrect, so in some cases it may not even match the devices offset.

I think if I had some Reflection code to just get the device's current offset (That may or may not included DST) then I can make my code work since all I care about is what 0/GMT looks like and what the device's current is to show it to the user right. For the object itself to work right GetTimeZoneOffsetAt will most likely need to do the same thing instead of what it is currently doing as it can't accurately figure the offset by number only.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is better to start a new thread for these questions as they are not related to this one.

1. There are countries with non-full hours time zones. You are correct that SetTimeZone should expect a double and not an int. It will be fixed.

2. There is no "y2k" bug when storing ticks as 64bit numbers. The latest possible date is:
08/17/292278994. There is a problem with unix ticks representation which is 32bit.

If possible please post some code that prints an unexpected time or date.
 

Roger Garstang

Well-Known Member
Licensed User
Longtime User
Ok. I had kept it here because the actual bugs still had to do with setting timezones and DST shifts which the original post was also about. Sounds like the first one was/will be fixed with timezones needing fractions. The ticks stuff was more of a comment as to why I was using the text representation of the date and a misunderstanding of data type naming in the example...I was thinking of Long as 32bit, but it appears JAVA misnames their variable types just like .NET- Int and Word are supposed to be 2bytes, Long/Double Word are 32bit and usually a Quad or Big Int is 64bit, but they changed the naming to make it confusing. I will have to remember to trust ticks in Android now...although the Date dialogs don't seem to indicate/trust it as much with their end date.

The 2nd and biggest bug is hard to put in code- To test I set the timezone in Android to Arizona. Arizona doesn't perform DST shifts. I then just ran a couple lines and printed toastmessages of the default TimezoneOffset and then of GetTimeZoneOffsetAt passing it Now. I first ran it at today's date then exited the app and did a force close otherwise the datetime object is retained in memory. Then I just changed the month to Jan in the OS Date. Upon running the code again it was shifted an hour for both. This is invalid. The object appears to have some sort of lookup table or something that just calculated DST by the numeric timezoneoffset. Since Arizona is the same as Mountain Time it just shifts it then which is incorrect. There are other areas like this, but Arizona is the easiest example.

There is also no way of returning the timezone of the object to the default timezone of the device and since it is a built in object it can't be dimmed/initialized again to reset it either. I was suggesting to fix both problems that it(GetTimeZoneOffsetAt) instead gets the devices timezone offset. I'm not sure how the passed ticks/time could be used unless the device can return what the shift would be for that date under the current device timezone, so since it is unable to accurately figure it by the offset number alone that part may need to be dropped.
 
Last edited:
Top