I am working on an application that allows a user to schedule an event. The user supplies an Olson time zone by using a Time Zone Picker, and a date and time for said event through an asp calendar picker and third-party ajax time picker (so the DateTime
supplied will always be in the same pattern). I compare the time the user wants and the time zone the user supplies with our server's time and its time zone, and fire the event the instant the user expects it to be fired.
From what I understand, having read this link at the nodatime google group, converting one ZonedDateTime
to another time zone (using WithZone
) is fairly straightforward (once I have the user's event mapped from LocalDateTime
to a ZonedDateTime
, obviously). I don't need to worry about offsets, and daylight savings time differences between, say, Pheonix and Chicago will be properly accounted for.
I had originally converted the server's time (DateTime.Now
) to a ZonedDateTime
and compared this way, but after reading this link on SO I switched to using IClock
.
So far in testing everything is working out, but I am worried about corner cases that I might not be testing for. According to the documentation for NodaTime:
The biggest "gotcha" is converting
LocalDateTime
toZonedDateTime
- it has some corner cases you need to consider.
I have read through the documentation thoroughly and I assume that this gotcha is in reference to those times of the year that either do not occur or that occur twice. These times will never be set as event times for our users but I do use the LenientResolver
for them. Are there any other gotchas - when I convert from LocalDateTime
to ZonedDateTime
, am I missing anything or will daylight savings time end up haunting me?
Also, do I need to convert the user's ZonedDateTime
to the server time zone before comparison (which I am doing now) or is this an unnecessary (or even erroneous) step? Will NodaTime be able to compare properly (without daylight savings problems) if I were to compare the event's unconverted ZonedDateTime
(instead of the event's ZonedDateTime
after conversion to the server time zone) to the current server ZonedDateTime
(see code below, third to last line)? When stepping through the code I can see the times and offsets, but I'm worried that doing this might be an oversimplification that introduces problems.
Protected Function EventIsReady(ByVal insTimeZone As String, ByVal eventDate As DateTime) As Boolean
Dim clock As IClock = SystemClock.Instance
Dim now As Instant = clock.Now
'server time zone (America/Chicago), unfortunately not UTC
Dim zone = DateTimeZoneProviders.Tzdb("America/Chicago")
Dim serverZonedDateTime = now.InZone(zone)
'user time zone
Dim userTimeZone As NodaTime.DateTimeZone = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull(insTimeZone)
Dim userEventLocalDateTime = LocalDateTime.FromDateTime(eventDate)
Dim eventZonedDateTime = userTimeZone.ResolveLocal(userEventLocalDateTime, Resolvers.LenientResolver)
Dim eventTimeInServerTimeZone = eventZonedDateTime.WithZone(zone)
Dim isReady As Boolean = False
If eventTimeInServerTimeZone >= serverZonedDateTime Then
isReady = True
End If
Return isReady
End Function
See Question&Answers more detail:os