Storing UTC is not a silver bullet
codeblog.jonskeet.uk
codeblog.jonskeet.uk
Events generally need to be locked to _something_ - whether that is UTC or a local time zone depends on the application.
The iCalendar standard (https://tools.ietf.org/html/rfc5545) generally gets this right.
It should operate like a good old paper calendar.
The feature set you're looking for sounds more like an "agenda" to me.
And that if the event arrives without having touched users in different timezones, then the software should infer that the event's timezone is the local timezone of all users at that point in time and space.
This is great not only for me but also for other people trying to schedule events in my calendar.
With Gmail picking up flight and hotel confirmations this could even be mostly automatic.
The explicit timezone is crucial for conference calls that cross timezones. That is at least half of the appointments on my calendar (I coordinate projects between the US, Europe and Asia).
In that case, you enter a recurring 10 am conference call every Monday, and the moment you move timezones you miss the call.
The problem really is (as mentioned in this thread) that the user's intent is not known.
I think the problem is the display: since you know you'll be in Germany from date X to Y, you should be able to configure the presentation timezone for those days (which would also show you those meetings in the local time when you'll have to make them).
The standard calls it a "floating" DATE-TIME:
"The recipient of an iCalendar object with a property value consisting of a local time, without any relative time zone information, SHOULD interpret the value as being fixed to whatever time zone the "ATTENDEE" is in at any given moment."
Settings - General - Use device time zone
If you disable this, you'll keep everything pinned to your preferred timezone.
But I'm pretty sure a better approach is to select the timezone of the event. If it is at 10am in Germany, why not tell your calendar about this? Sure, this is an extra step, but it is part of the event's parameters (as pointed out in the OP).
This is something we (startup insurance company) have thought about a lot actually. Since the certificates we issue are relevant to a particular jurisdiction, if the document states e.g. "23:59:59", it means the "wall clock" time in that jurisdiction - whatever point-in-time our DB contains isn't really that relevant.
So the likely problematic situ is if we've got a policy end date/time more than a year in advance, then the country changes their TZ offsets, we need to make sure our point-in-time records get updated (and then of course the duration of the policy changes). It's a bit of a pain in a system built around immutable events!
On a kinda related note, we also took the decision to clearly define that our start/end date-times have a resolution of one second and are inclusive. So if a policy starts at 00:00:00 and ends at 23:59:59, that's the full day, all the way up to midnight. It also means then it's important that we render the full time (incl seconds) on our docs.
How would you deal with the current EU situation? They have recently voted to stop yearly transitions to summer time. But there must still be a timezone assigned to an event.
Are you assigning timezones (in the certificates themselves) as the timezones of a particular geographic location,, rather than as time offsets?
Logically, we think of it as the "wall clock" time, plus the location ("Europe/London" - we don't operate outside the UK yet), plus the local zone (BST/GMT) to handle ambiguity when clocks go back.
Practically, right now the start/end date-times are stored using a Postgres timestamp with no timezone. As we've never issued an individual policy of more than 28 days' duration or more than 7 days in advance, we've never actually had to deal with any situation where the point-in-time is no longer correct. And this case is not likely to happen without a decent amount of notice.
We're very much in favour of abolishing seasonal transitions though - causes lots of confusion.
In the jurisdictions you care about. Last-minute timezone changes do happen, and the main time zone database has been updated retroactively in the past. It's actually possible that a timezone change has even been enacted retroactively (thanks to countries that like doing very last-minute DST starts).
One day we will need to deal with it and conversations like these are super helpful to support that.
On the other side, sometimes we don't know where an event happens. Think of GPS trackers close to a border which is also a timezone border. This is a more complex problem which requires at least a model of country borders and maybe roads.
Finally, on some systems I'm using as a user, they have some EU timezones but not even all the major countries. It doesn't matter now but it will. I expect they'll add the missing timezones and make us confirm where we are.
Representing future times correctly is very hard, especially because time zone changes (including creation of new ones!) aren't always announced years in advance.
Any incidents along the way or after that are going to need an interpretation relative to UTC.
If you had a policy for the calendar year 2016 would it not have covered 31 December 2016, 23:59:60 then?
https://www.timeanddate.com/time/leap-seconds-background.htm...
Never trust user input though, of course :P
Obviously for actual timestamps - e.g. created at/updated at times - we do store a point-in-time with fractional seconds.
From an operational perspective, if there was an incident in the second between 23:59:60 and midnight, it would of course be covered - irrespective of what's in any system, written on any doc, displayed in the app, etc.
We don't worry too much about leap seconds - particularly as very few people are even likely to realise it was a factor, and the national Motor Insurance Database (MID) does not support them.
The MID doesn't even allow us to specify timezones, so every year we sell around 20-30 one-hour car insurance policies which appear to run for 1 second - displaying the same start and end time on police computers etc. (Due to the clocks going back from BST to GMT.)
From a legal perspective, the time written on the policy doc is inclusive - we can't just decide that we want it to be exclusive because it suits our purposes.
Well, apparently it's not if it's understood that it covers leap seconds as well. With regard to the internal modeling, I always go for half-open intervals, where the open side depends on the data being modeled, they have much nicer mathematical properties than closed intervals.
valid_from: 2019-01-01T00:00:00+x
valid_until: 2019-01-02T00:00:00+x
Even 23:59:59.9999999 would still be < valid_until without any special tricks.
I think python3's datetime has something like what you're pointing at -- objects are either timezone-aware or not. My complaint probably has to do with trying to hide this distinction from the user, when it would be more helpful to make it clear.
I would not be remotely perturbed if my phone had a pop up when I stepped off the plane asking me if I still wanted to wake up at 7AM local or would prefer to wake up at 10AM UTC.
I would be greatly perturbed if it assumed the latter and I missed my meeting, all because I forgot to set a timezone when I originally inserted it a month prior.
I use both quite a bit. I'd definitely rather not be asked every time - especially since I work at night and do most of my email management in that timeframe
In that specific case, it woke me up according to local time, which is what I expected. But what if I had crossed the time zone boundary less than an hour before I wanted to be woken up?
Going the other way is a more fun problem, but a few hours of debouncing is fine for anyone moving at suborbital speeds.
It’s my calendar, why would I set it to events in a way that’s not relative to my time reference?
For instance, say there's an 1pm CT meeting every Tuesday for a remote team. When I head to the East Coast for a week, that _should_ mean 2pm ET, but if the assumption is "1pm when I'm there", since the "there" has changed if my calendar doesn't adjust accordingly I'm going to be an hour early to the meeting.
It's also very useful that you can set the left margin (in the web app) to show two different time zones in a "ruler" format. So even if your overseas appointments for later in the week are displayed in terms of your current timezone, a quick glance across will confirm what their "local" time will be once you're on the ground.
The upshot is that if I travel and change my Mac's clock to local time, all of my events get screwed up. The first time this happened I nearly had a heart attack because I have years of history in my calendar. So I always leave my Mac's clock set to my home time zone and do the conversion in my head.
Sort of a summarization of most of the ideas here is:
* for clear instants like a system log UTC makes sense
* for times in the past (far enough in the past that you know your current TZ rules are correct) UTC makes sense.
* for the immediate past (near enough where your rules might not be correct) you might want to store zone as well.
For all cases of times in the past, remember that you're trying to record an instant. An exact unambiguous point in time that is the same irrespective of who is looking at it or where they are. For this UTC makes sense - people who see that instant converted to their local timezone are noting what their clocks would have shown at that instant, but everyone who will ever see it is always referencing the same instant.
FUTURE times are very different. There are times at which you want to reference a future instant, at which point you can just use UTC, but most often what you really have is "this is what I expect to see on my wall clock when this thing happens". That is a very different beast, because nobody knows what the timezone rules or geopolitical situation will be when that thing does happen.
You need to recognize the use cases where what you mean is " I expect to see XX:YY:ZZ on my wall clock when this happens" and just record that information as is, including as much information as you can about that wall clock - possibly which timezone it (currently) uses, where it is (in case the timezone itself changes) and then convert to an instant at the last possible moment, or keep updating your instant based on changing rules.
In the particular case of employment I'd assume there was as implicit time as well, because employment would be a legal contract (whatever the precedent is in that jurisdiction would probably apply). You couldn't do something that's against your contract on the way to work on your first day, for example, and claim that it didn't count because it was before office hours.
Legally, employment usually has a well defined start date and end date - and it often simply doesn't have a well defined start datetime and an end datetime, you might as well assume that it's undefined unless/until a particular situation forces you to get a court ruling for that.
We allowed users to define schedules which would control light, temperature, co2, irrigation, etc for greenhouses. Those schedules would load into on premise controllers and run for weeks or months.
They might be built by a user in one timezone and deployed to multiple facilities in different timezones. They often ran across DST boundaries, and some users wanted them to follow "wall clock time" while others wanted to ignore DST to match the behavior of legacy control systems.
The blog posts brings up a lot of good points about time zones changing, and the comments make even better points about people moving across time zones. Something that confounds me occasionally is the concept of "local human time" because there are all sorts of ways that humans tamper with time.
Lawmakers, for example, that are required to pass certain laws by a particular date will sometimes unplug clocks in the legislative chambers to stop the legal passage of time while negotiations continue. You end up in a situation where, on paper the next day or week, 134 laws were negotiated, voted on, ratified, re-voted, passed, and signed all at exactly $date:23:59:59. A physical impossibility, but a legal fact.
Or, as I explore the more interesting corners of America more, there are entire towns and regions that ignore their official time zone and every house, business, church, pharmacy, etc... is on a more convenient time for the locals. The only place you see the official time is at the post office.
People are messy. Time is messy. People * time = a complete mess.
Is this internationally accepted or a USA-only thing? It seems like fraud to me.
This also matches common usage - if I tell you what I did on a friday night, it'll include both things before and after midnight.
There are also parallels in banking where business days don't align with calendar days, and you may have (depending on regulations and agreements) either a "long friday" or "long monday" where an action that's physically performed on a sunday will be treated with an effective date of friday or monday respectively; or possibly events after the closure of a business day may be legally treated as happened in the day after.
Someone could be born before you, yet you have an earlier birthdate than them.
They are really different things.
Offtopic: One time the Cardinals of the Catholic Church couldn't come to an agreement over the next Pope. After a few months of that the Holy Roman Emperor or some such had workmen remove the roof and locked them inside. A day and a half later, new Pope!
Fascinating, and I've never heard of such a thing. Are these towns near a time zone line, that find it more convenient to be in the time zone of a nearby large city on the other side?
I've seen both, and neither.
Sometimes it's it's because they're in a deep valley and the sun rises much later than the rest of the zone they're in.
Use timestamp with tz, drop Unix timestamps and use ISO8601 DateTime format across the application ezpz never look back
https://www.postgresql.org/docs/9.1/datatype-datetime.html
"For timestamp with time zone, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone. If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system's timezone parameter, and is converted to UTC using the offset for the timezone zone."
'timestamp with timezone' is kind of a gotcha. i guess it combines two things into one type that are logically one type but it also might mislead someone into believing the type is something else.
When you store something as timestamptz, postgres converts it to UTC and "loses" the timezone part.
The only difference between timestamptz and timestamp is that when postgres is returning the timestamptz to you, it converts it back to your local time zone defined by SET TIME ZONE (and not the time zone it was originally stored in)
So basically if you store a timestamptz, you cannot convert it back to the local time, as the local time is never even stored.
I personally had to add a second `timezone` column to my table to store the timezone of the date.
E.g., when you do store the timezone separately, use `timestamp without time zone`: `time AT TIME ZONE timezone` [1] only does the right thing (i.e., interpreting `time` as relative to `timezone`, and producing an absolute time corresponding to it) if `time` is `without time zone`. (If `time` is `with time zone`, it produces the local time corresponding to the absolute time `time`, which is mathematically exactly the opposite of what you want.)
[1] https://www.postgresql.org/docs/current/functions-datetime.h...
Unfortunately the poor naming is a big faux pas.
I really really expected timestamp with time zone to store the time zone.
For calendaring or other applications where time zone’s shifting offsets can cause issues you need to store the UTC time along with the timezone and then do the conversion on read.
Indeed it doesn't solve the problem of handling user-inputted "human" times correctly. But that is a much rarer case than needing to handle "system" times. Many - probably most - applications never need to handle a "human" time at all.
Leap seconds mean the same UTC time can happen twice if we fall back a second, or a UTC time may never happen when we skip ahead a second. Leap seconds also mean that epoch milliseconds derived from UTC do not represent milliseconds between the timestamp and Jan 1 1970 unless the conversion is aware of all leap seconds. Leap seconds are prescribed every six months with six month notice. There are many time keeping devices that are not updated as often as UTC leap seconds are introduced.
I'm pretty happy with ISO-8601, but dates after the year 10,000 will not sort lexicographical. A 64 bit signed int storing milliseconds since Jan 1 1970 covers 29225733 B.C to 29229672 A.D
Isn't this an argument against using TAI in certain applications though? i.e. if you're designing a system which relies on non-leapsecond-updated devices to be in sync with devices that are capable of being updated, you should always design as such to accommodate the former rather than the latter?
UT1R is a time of day measurement that is based on making astronomical observations to establish the Earth's angular velocity and phase very precisely with respect to TAI. Leap seconds are created from time to time to keep the offset between UTC and UT1R to less than a half-second.
In effect, UTC is slaved to UT1R via a PLL that is only capable of making phase jumps. Instead, we could have slaved UTC to UT1R via a PLL that only ever made frequency changes. There would be no phase jumps (leap seconds), just very subtle adjustments in clock frequency. Those adjustments are fine enough that the majority of users don't care. The remaining users were already using TAI anyway.
We can't phase lock real seconds to calendar seconds, because calendar seconds are a moving target. As the Earth's rotation slows, calendar seconds get longer. Seconds that get longer are not acceptable in science.
Sure you can, and yes they are. There can be a difference between calendar seconds and atomic seconds. For most applications the difference is irrelevant. People doing science can explicitly account for the differences. And since most time-keeping in science is much more inaccurate than the difference between the speeds of TAI and UT1R, those folks won't care.
Most of the applications that do require very precise timekeeping actually only care about having a very consistent timebase, they don't necessarily care as much about the speed of time. So even if we steered GPS time by enough to use it as a broadcast source of UT1R, the majority of users who use GNSS to synchronize their measurements also don't care.
The remaining handful that do care are going to be purchasing atomic clocks anyway, and there are dedicated mechanisms available to synchronize those to TAI.
The united states will experience this soon. California and Washington are independently seeking to end daylight saving time. There is no America/Portland or America/Seattle so Washingtonians and Oregonians are using America/Los_Angeles. Unless Washington, California, and Oregon end Daylight savings on the same schedule we'll have to add new id's and users will have to change their configuration, and we'll still have issues described in the link.
Civil time is different from atomic time and different from sidereal time or solar time.
Civil time is how people, businesses, and governments organize and plan their activities.
Atomic time is monotonic, physical, and "more objective" / less dependent on legislatures :)
Sidereal time is about the orientation of Earth relative to stars. It's really important if you're an astronomer.
UTC is a civil time standard based closely on TAI, an atomic time standard, except it gets corrected to be within 1 second of UT1, a sidereal time standard. It is basically _the_ civil time standard and it is a little compromise to make a civil time that advances like atomic time but also does not desync from sidereal time.
Different administrative regions use offsets from UTC to determine their local civil time.
If you're writing an application where people plan future activities and you really want to "get things right / not surprise users", you probably need to store times in the appropriate civil time standard, make it apparent _which_ civil time standard is canonical per activity if people are being coordinated across administrative regions that do not synchronize their standards, and ensure that your application can find out about planned changes to civil time in any of the administrative regions of interest.
https://zachholman.com/talk/utc-is-enough-for-everyone-right
It is more high level but a very good read on the subject.
> And then someone will calmly quote this passage in response, quietly pleased with themselves that the initial commenter was rude and certainly didn’t read the post at all. Then a third person will chime in on the thread saying the author was playing you all like a fiddle anyway, and the real problem is that the post was way too long to start with.
It's funny that it predicts my comment as well, touché.
For example if I travel and take photos I don't want their mod times to be of those back home, which can be in the middle of the night or wrong day.
Have been moving them to my local timezone via a time shift, but not sure that is the right thing to do. Now they are in my timezone, but if I move one day, will I have to update all my photo times? Even with exiftool and DateTimeOriginal, that's more file updates than I'd like to do.
For instance, Emperor Hirohito went to bed on December 8, 1942. A few hours later, bombers attacked Pearl Harbor at December 7 local time.
Let's say Event A happens in New York (Eastern Time Zone) at 2018-12-08 02:00 UTC, and is recorded as occurring on 2018-12-07 (with no time) local time. Then let's say Event B happens in London (GMT) at 2018-12-08 01:00 UTC, and is recorded as occurring on 2018-12-08 (with no time) local time. Which event happened first? If we know the UTC times, a reasonable person would say Event B happened first. But if we just have the local dates with no times, we either say that Event A happened first, or we say we don't know.
This is a real problem I have to deal with and it is a pain. One user says A happened first, another says B happened first, another says A and B happened at the same time, and I say "give me the UTC time or you don't get this feature" :)
The day the Russian revolution began on 25 October 1917, it was 7 November 1917 in England.
$ cal 9 1752
September 1752
Su Mo Tu We Th Fr Sa
1 2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30The nature of the problem is that when you convert from a local timestamp to UTC, you might have been "wrong" in the conversion. Or, more specifically, it may have been as correct today, but it may become wrong some time in between now and when the timestamp occurs, because of future time zone definition changes. A future timezone definition change may mean you should have converted to UTC differently, which you couldn't have known because the timezone definition change happened after you converted. (Usually statutorily; sometimes maybe because your timezone data was wrong and was later corrected?)
I don't believe these problems apply to _past_ dates or "right now" timestamps. Unless your timezone data is wrong I guess.
Does this seem right?
As the article explains, though, present and past timestamps can be impacted too - your timezone library may be out of date at the moment you save the timestamp, or in some cases the legal body defining the timezone may reach into the past with a timezone change.
All those people on Monday that _thought_ it was 1pm, it turns on Tuesday we decided it was actually 2pm when they thought it was 1pm. But nobody could have known that on Monday. So they've got to... go back and change any times they put on documents on Monday? How does that make any sense?
But incorrect timezone data or implementation is too real, true.
I'm not aware of any specific examples, so perhaps I'm being too paranoid in my first post, but it would not surprise me in the least to hear of, for example, a bill to eliminate DST in a state that somehow manages not to pass until a day or three after the DST change takes effect.
There have at least been some some bizarre calendar changes that many software systems fail to accommodate, which probably feeds into my above paranoia:
https://en.m.wikipedia.org/wiki/Soviet_calendar
https://mentalfloss.com/article/51370/why-our-calendars-skip...
That's because some governments are pretty sloppy about announcing their timezone changes in advance. It's compounded by the tzinfo DB being maintained by volunteers (who can't spend their lives obsessively gathering timezone change announcements the instant they're made), and the lead time necessary for software projects to update their tzinfo instances [2].
So, while retroactive changes may not be consciously made often or ever, it's certainly an effect that happens in practice.
1: https://data.iana.org/time-zones/theory.html#accuracy 2: https://codeofmatt.com/on-the-timing-of-time-zone-changes/
- store past dates in UTC
- store future dates in the format that makes sense, based on what the truth is. Scheduling event at 9AM local time? Use local time. Determining when the spacecrafts meet? Use UTC (or Federation Standard Time if you prefer ;) ).
When a user inputs a time, let's say for an alarm, this is always "wall clock", and this is what you store. The timezone can be stored too, but this is also dynamic. For example, a user put a conference in a calendar at 7 am, this is dependent of the user location the day of the conference.
For app following the user, this is simple (like a mobile app), you just use the current timezone of the system the app is running on, but for a distributed system (client server), it might be complicated to pick a timezone and is dependent of the application.
For computer times (like logging, cron...), just use UTC.
If we decide that the conference's start may be a moving target based on changing DST rules, then our coutdown timer cannot smoothly count down. At every tick, it has to evaluate the amount of time left to the conference start, and show that. The conference start's local time is always converted to UTC based on the current rules; when the rules change, it jumps by one hour and so the countdown timer adjusts itself at the next tick to show an extra hour.
You can't smoothly count-down toward something that starts at X or at X + 1h, and you don't know which until later.
All the dates stored in UTC which move due to a DST rule change have to be traversed and updated, as do any dependent countdown timers. That doesn't mean it wasn't "correct" to store them that way.
"Correct" means that we handle all the cases in our specifications and design, and they are translated to code without mistakes.
People like countdown timers. If there is going to be a countdown timer to an event whose time is uncertain, that countdown timer has to update itself when the exact time is pinned down. Until then, it should probably use the shorter countdown so that it errs on the side of too early. It has to be updated whether the time is stored as local time or as UTC. The behavior of the countdown timer cannot depend on how the time is stored in some database.
Store absolutely everything in UTC, do all calculations on UTC, and show in whatever timeunit the user wants. The one edge-case where user inputs a local time thats is not unique (repeated hour due to daylight savings time) can easily be solved consistently, and often is not even a problem at all.
Here's a use case: You and I are agreeing to meet at a given landmark. This could be any landmark in the United States, just to keep it simple. The user experience is: you propose that we meet at <landmark> at 4 PM tomorrow, and I agree. This happens on a website.
As far as you, me, and most of the system is concerned, the only sensible way to store that time is as a timezone-agnostic, UTC-agnostic local time: "2019-03-28T16:00". That's because, for the system to store that time as UTC, we have to know the UTC offset of every landmark in the United States at any point in time (which isn't an easy problem!) and consistently, correctly convert between UTC and that local time every time it gets displayed anyway. If we screwed up the UTC offset when we stored it the first time, we have to change the UTC time.
Now, if there's an additional constraint that you can only schedule meeting times that are actually in the future, you have to know what times constitute "the future" relative to the UTC offset of the landmark, so you don't get out of needing a comprehensive UTC offset map of the United States. But if you screw that up, you just end up putting an irrelevant or impossible meeting time in a dropdown and maybe dealing with some users attempting to time travel. Even that is a failure mode that users will somewhat understand, but most of the time it won't matter unless users are scheduling within the same time window as your UTC error.
If you stored it in UTC, you'd be screwing it up all the damn time until you fixed your UTC offsets, at which point previously-working data would be incorrect because someone would schedule a meeting 8 days out in one of those geographic regions for 6 PM and suddenly wonder how it got shifted to 5 PM for no reason.
Now, if we're scheduling a meeting online, and videoconferencing instead of traveling to the Navajo Reservation in Arizona--of course we store it in UTC. And if some of us are traveling to the Navajo Reservation[1] and some of us are dialing in from Newfoundland[2], we're all fucked anyway.
[1] The Navajo Indian Reservation spans multiple states, including Arizona. Arizona does not observe DST. The Navajo Indian Reservation does. However, inside the Arizona portion of the Navajo reservation, there is a Hopi Indian Reservation, which does not observe DST. Inside of the Hopi reservation, there is another part of the Navajo reservation that does observe DST.
[2] Newfoundland's UTC offset isn't an integer number of hours, there's an extra half hour in there. Enjoy!
I should add that where we store UTC that concerns a place, we also know/store that place in lat,long (or anything that resolves to this) and use that to show it in any timezone, to any user in any timezone, ..even in any era (yes places can change timezone).
I live in Seattle, I set a reminder on my phone one minute before new years 2021.
date --date "2021-01-01T07:59+00:00"
Thu Dec 31 23:59:00 PST 2020
Currently Washington follows daylight saving time so we'll be using PST on new years eve.Washington lawmakers are considering a bill to end daylight saving time. If it passes then new years eve 2020 will be PDT, not PST
2021-01-01T07:59+00:00 is midnight PST but it is 1:00 AM PDT and my alarm will be off by an hour.
storing in UTC is fine as long as your clients are time zone aware and can convert to local and send timestamps with time zone so that the server can convert back to UTC.
the "options" provided are just examples of how not to do it.
NOW... it gets even more interesting for recurring events. Does 11AM on Tue mean 11AM on Tue after daylight savings? How about events like Shabbat candle lighting times that depend on when the sun sets?
It took us a while to do all these. Does anyone know a good non-API solution to timezone calculations / shapefiles feed?
* ID: auto-incremented integer
* Name: string
* StartTime: date/time in UTC
* Address: string
* TimeZoneId: Europe/Amsterdam
* RuleEffectiveTime: date/time in UTC
The rule effective time represents when the start time was last changed, converted to UTC.
Next, create a time engine that can convert between events (time + location). The engine can convert events to different time zones in different epochs, to UTC, or the other way around, because it knows all the rules, and when the rules changed throughout history. A simple API will handle things:
time time_engine.parse_time(rule_effective_time_event, string_representation)
String time_engine.to_presentation_string(rule_effective_time_event, time_value_utc)
Where time_event is a tuple consisting of the rule effective time, and the timezone whose rules to apply.
When the venue changes, you update TimeZoneId. When the start time changes, you change StartTime and RuleEffectiveTime. The time engine would only be invoked to present the start time in current time + zone format for the user to modify in their own temporal space, then to parse the changed time back to UTC using the user location + new RuleEffectiveTime (which is now).
Timezone rules are fixed as events in time and space, so every rule effective time + time zone + utc_time will uniquely point to a specific time zone rule, which means that the rule itself doesn't need to be stored in the database.
Timestamps are also fixed, and should never change (unless the user changes the time for the meeting, of course).
You could build the time engine to preserve absolute time (14:00 becomes 15:00 after the rule change), or to preserve local time (14:00 remains 14:00 after the rule change, even though it's technically a different time). You could even change how the engine behaves after data has been created, since it's only affecting how things are interpreted locally to the user. The data remains the same no matter what.
The database's role is to store data, not to decide rules. Store the data, not the rules.
Handling calendar times and recurring times have their own complications.
If you want to compare e.g. two charts of temperature over a 24-hour period between two places, you want noon for both to be in the same place on the X-axis. So you want to use local time of both places.
But if you only store UTC, you don't know local time.
No need for tzinfo changes or travelling through time zones.
I currently have several recurring alerts in my calendar app. One of them is an alarm everyday at 10 p.m. This must be in local time everywhere I go. Another is a conference call at 10H30 a.m on Wednesdays, Pacific Time (not my timezone). If you treat them the same way one of them will be wrong when I travel.
"Time zone history" (in every platform I've seen) does not mean "knowing what the rules for 2022 were in 2019". They mean "getting things right according to all the currently-known rules, across all of history". That's very different.
e.g. if you store your logs with a UTC date you'll see interleaving logs for the extra hour, or if you read sensor data or something like that you'll get double readings?
>>> loc_dt = datetime(2002, 10, 27, 1, 30, 00)
>>> est_dt = eastern.localize(loc_dt, is_dst=True)
>>> edt_dt = eastern.localize(loc_dt, is_dst=False)
>>> print(est_dt.strftime(fmt) + ' / ' + edt_dt.strftime(fmt))
2002-10-27 01:30:00 EDT-0400 / 2002-10-27 01:30:00 EST-0500
https://pythonhosted.org/pytz/#problems-with-localtime"Call me at dinnertime, say 7." "My 7 or your 7?"
Is a lot easier than
"Call me at 0400" and having both parties do offset math in their heads.
I live in Seattle, I set a reminder on my phone one minute before new years 2021.
date --date "2021-01-01T07:59+00:00"
Thu Dec 31 23:59:00 PST 2020
Currently Washington follows daylight saving time so we'll be using PST on new years eve.Washington lawmakers are considering a bill to end daylight saving time. If it passes then new years eve 2020 will be PDT, not PST
2021-01-01T07:59+00:00 is midnight PST but it is 1:00 AM PDT and my alarm will be off by an hour.
For most use cases when a users enter a datetime in the future, they do not care about how many seconds from 1970-01-01 that point is, they care that it occurs at exactly 12:30 on that particular day.
Its amazing how complicated your life can get when reporting across time zones and then mixing that with legal requirements for some reporting.
Also, time zone id and local time is insufficient unless you keep reference tables that can calculate what offset was in effect at the time of the event. Save the trouble and just record it along with the time stamp.