❔ Accounting for Daylight Savings Time skips at runtime
My Discord bot I am developing has a reminder system which utilizes https://github.com/robbell/nChronic.Core for natural date/time parsing - allowing a user to specify a reminder for
tomorrow at noon
. As not everyone lives in the same timezone, users can configure their timezone via a command, where the user inputs their approximate TZDB equivalent (see image).
The bot also supports repeating reminders, IE a reminder where a user can be reminded hourly, daily, or weekly at the same interval of time - IE, a reminder to do something at 10PM daily.
As I just learned this past weekend with the time changing, this system has a flaw, where anyone whose region observes DST will have reminders become off by an hour once it begins or ends.
My current system involves storing the user's offset from UTC as a TimeSpan
for parsing purposes, and then storing reminders as DateTimeOffset
relative to UTC regardless of their timezone (because Npgsql's EFCore thing seems to only support UTC offset?). Is there any way to account for this behavior? Especially since it's not something observed worldwide, and even in America, it's apparently on the way out and some regions don't even follow it10 Replies
I noticed because I have a daily reminder for 10PM, which went off at 11PM today, and I realized it was because of the time change.
for your own sanity, I suggest switching to NodaTime, which has support for actual time zones https://nodatime.org/3.1.x/userguide/type-choices
npgsql has support for it https://www.npgsql.org/efcore/mapping/nodatime.html
I'm actually using NodaTime for the timezone parsing, that's where I'm getting the TZDB info from
Unless I'm wrong, this still doesn't seem to account for DST switchovers, unless you're telling me nodatime is somehow aware of these at runtime and can account for it
(if it matters, the way I "expire" things like reminders is by sorting them by which one's expiry date is lowest)
oh wait
hm
you might be right
I'm really not familiar with NodaTime, I actually tried using it instead of the BCL stuff for this exact stuff originally since I was actually storing their timezone as a TZDB string (IE
America/Chicago
instead of a TimeSpan, but I was either a) getting tripped up on some of the conversion methods to/from BCL types, or b) came across an issue I couldn't solve using NodaTime. This was...a month or so ago so I honestly don't rememberyou've now nerdsniped me think it would work if you stored a LocalTime (which is a time of day with no timezone) plus a time zone ID in a separate column...
i'll have to probably do some testing before I mess around with my db entities...not even sure how to test it. maybe just have a LocalDateTime of just before the changeover, convert it to a ZonedDateTime, then repeat the process after the changeover, and see if the difference is correct?
You might be onto something. Here's my findings:
it jumps from 1:55 to 3:05 AM, indicating it was "aware" of the changeover at 2AM
@jcotton42 sorry, meant to ping reply, but discord broke the message sending it would probably make the most sense to store the user's TimeZoneInfo in the db and then store reminder expiry as a LocalDateTime (UTC), then convert to a ZonedDateTime on the fly
assuming the npgsql thingy supports those two, i'll look into it tomorrow
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.