Xojo Blog: Better Dates

This blog post couldn’t have come at a better TIME (see what I did there?)…

I had some date/time code that broke over the weekend when the time fell back from Daylight Saving Time. My code schedules audio events to begin playing at exact times.

Is there a way to detect for the DST change, or even better, predict it? Does the new Date class deal with that?

the switch-overs are fully documented as to when they happen… and the dates can be calculated if I’m not mistaken… after all you computer KNEW to change without being told :slight_smile:

Right, but is there a way to determine if the switch has happened already? If my program is started at 1:15am, how can I tell if it’s the first 1:15 or the second 1:15?

count the ticks
when app starts … remember the ticks
if an extra hours worth of ticks happened then the switch has occurred

[quote=357833:@Dave S]count the ticks
when app starts … remember the ticks
if an extra hours worth of ticks happened then the switch has occurred[/quote]
Actually… ticks is time since the computer started up, so it probably doesn’t help. As far as the new date class goes, even the SecondsFrom1970 shouldn’t have overlaps because of DST and that’s kinda the point of the new date class. Much more consistent when it comes to measuring time considering time zones and daylight changes.

Daylight time has sprung forward & fallen back on different dates in different places since its inception (although it is much more consistent now)
The new date class handles this situation much better than the old
Imagine you have a datetime stamp that is some point in time in the past and you want to figure out if daylight time is or is not in effect (which may be material to whatever it is your doing) so you can display something like EST or EDT (or MST vs MDT etc)
This was a pain in the butt to figure out before (been there and had to do exactly this)
The old date class has no way to say “this date and time in this locale” because ALL it has to work with is GMTOffset - which is what you’re trying to figure out - with daylight time one it is usually 1 hour different (although not always - thanks Newfoundland - which is currently -3:30 from GMT)

It is much simpler now

// app start
startTime=new date
startTicks = ticks
nowTime=new Date
x=(nowTime.totalSeconds-startTime.totalSeconds)/60
y=ticks-startTicks
// x and y should be equal if elapsed time was all during DST or not
if x<>y then DST changed..... sign of X determines if it started or ended during the elapsed time

the OP wanted to know if DST changed during an elapsed period of time…

[quote=357852:@Dave S] // app start startTime=new date startTicks = ticks

nowTime=new Date
x=(nowTime.totalSeconds-startTime.totalSeconds)/60
y=ticks-startTicks
// x and y should be equal if elapsed time was all during DST or not
if x<>y then DST changed..... sign of X determines if it started or ended during the elapsed time

the OP wanted to know if DST changed during an elapsed period of time…[/quote]
That only works if the time zone that you are currently in observes daylight savings time. For instance, if the app were running in Arizona, there would be no change.

Is also worth noting that because Ticks returns an integer, and if this code were running on a server that runs 24/7, ticks is only good for 414 days in a 32-bit app.

right… and in Arizona what the OP seeks would never happen… so his app would never experience 1:15am twice… actually it never would seeing as in the US… the change happens at 2am… but that is neither here nor there.

[quote=357831:@Dave S]

begins at 2:00 a.m. on the second Sunday of March and
ends at 2:00 a.m. on the first Sunday of November[/quote]
To make it more complex.

[quote]In Europe DST:
begins at 2:00 a.m. on the last Sunday of March and
ends at 2:00 a.m. on the last Sunday of October[/quote]
:wink:

While Geoff’s blog is more to do with timezones than the time spend/saved between the two methods (at least that how I read it) I personally prefer the following:

Dim d As New Xojo.Core.Date(2017, 11, 5, Xojo.Core.TimeZone.Current) MsgBox(d.AddHours(3).ToText)

Its super easy to read and takes less lines than all the previous examples.

Or this if you want to modify d, still a LOT easier to read.

Dim d As New Xojo.Core.Date(2017, 11, 5, Xojo.Core.TimeZone.Current) d = d.AddHours(3) MsgBox(d.ToText)

This is done with my custom Module Method:

Public Function AddHours(Extends d As Xojo.Core.Date, hours as Integer) as Xojo.Core.Date Dim di As New Xojo.Core.DateInterval(0, 0, 0, hours) Return d + di End Function

Whether or not its included in the Xojo framework is up to the powers that be as they might not like framework bloat for the sake of implementing something that could be done in a few minutes with the existing framework. The problem there is that someone coming from .Net might see the lack of this feature out of the box as a step back even before they find out what Extends can do which could be a loss of someone to Xojo.

I’ll put this in as a feature request when I get back later this evening and see where it goes.

In both the old and new add 1 year, 1 month, 1 day and 1 hour
The old date requires you do this in the right order - or you get VERY wrong results
The new one doesn’t

Being able to get it right without having to know that “magic” is valuable

I will also reiterate what we’ve said before
DO NOT assume that what you have today in the new frame is all that there will ever be - there will be additions