2

I try to store the datetime (that is a calendar-date with a clock-time) in a table.

As far I read the type DATETIME does not have a timezone.

And type TIME is limited from the year 1970 to 2038.

I live in a country with a different timezone in summer (CEST) as it is in winter (CET). So there is a double hour 3 when we switch from CEST to CET.

When I am not able to have a datetime with the timezone included and I need to differentiate this hour 3, then I see no way but to handle it manually.

e.g. have another column for it or convert any DATETIME into UTC.

Is that the only way or did I miss something?

chris01
  • 10,921
  • 9
  • 54
  • 93

3 Answers3

6

It depends on what you are really doing.

  • An "event" calendar -- The concert starts at 8pm in a particular time zone.
  • A universal time of when something happened.
  • ... (There are about 5 different needs for timezones.)

MySQL/MariaDB has only 2:

  • DATETIME -- think of as a picture of a clock. It's what you see in your timezone.
  • TIMESTAMP -- think of it as this instance in the universe. Or think of as being implemented by converting from your timezone to UTC and the UTC value is stored. (And converted back when you SELECT it.)

If either of those works for you, then use it. If not, I might suggest storing a TIMESTAMP plus a timezone offset (in minutes) but this only works for historical data. All offsets (currently) are (I think) in multiples of minutes (full hour, off by 30 minutes, or 45 minutes). (Netherlands once had an offset that went down to the second.) Most countries are some multiple of an hour away from UTC. India is the biggest country with a half-hour offset (since it is one timezone for the entire country) but there are many other time zones that have half hour offsets (Australia/Adelaide, and Australia/Darwin) or even 45 minute offsets (Pacific/Chatham), and some have daylight savings (Australia/Adelaide) whilst others don't (Australia/Darwin, last DST change was in 1944).

Rick James
  • 135,179
  • 13
  • 127
  • 222
1

You will generally avoid a lot of headaches by storing times in UTC. Then there's no 'double hour 3', the arrow of time just marches inexorably forward :)

I'm writing this answer at 14:27 CEST, which would be stored as 12:27 UTC in a database. If I wanted to present times in a form familiar to an end user, I'd have them pick a time zone from the Olsen database, and use that to figure out the correct offset (or store a timezone as a separate column if you wanted to always show the time in that zone).

See this excellent question/answer for more depth, including lots of links for timezone handling in various languages.

Paul Dixon
  • 295,876
  • 54
  • 310
  • 348
  • So you do also not see any possibility to have a timezone in MySQL builtin? – chris01 Jul 26 '19 at 12:54
  • 1
    You can use the `CONVERT_TZ` method to write queries which combine a datetime and a timezone or offset, but that's as good as it gets (and to use timezones, you need to ensure you maintain mysql's built in Olsen data). See https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_convert-tz – Paul Dixon Jul 26 '19 at 14:14
  • 2
    @chris01, builtin datetime and timestamp with time zone, as of version 10.4, are still on the [mariadb roadmap](https://jira.mariadb.org/browse/MDEV-10018). – Tano Fotang Jul 28 '19 at 15:39
  • [Storing UTC **is not a silver bullet**](https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet)! – YektaDev Aug 22 '21 at 07:53
0

In general (and the most common use case) store timestamps with a timezone, preferably UTC to save on conversions going in and out and dealing with timezone differences in comparisons. This should covers all historical and fixed point in time events (such as logs, or "event occured at", "item was changed/created at"). ie. the TIMEZONE type

For calendar events, special rules apply.

  1. Is it a Future and Absolute time? store it with the IANA timezone string, don't convert to UTC. Timezone changes will not affect the event time unless the timezone was deleted (unlikely to happen). ie. DATETIME and a second field of type VARCHAR() to store the timezone such as Pacific/Auckland, or Australia/Sydney.
  2. Is it a Floating time for a future (possibly recurring) event such as "Lunch is 1hr long every day from noon", the occurrence cannot be pinned down to a fixed point in time until it can be resolved down to having a timezone. So if you need to store these, then store them as DATETIME.
  3. Is it a recurring event? Don't store the timestamp for each event in the future, store a recurrence rule using the logic provided in RFC5545 so that you can easily generate future events. This means storing the Start time (DTSTART) of the recurring event either with or without timezone, recurrence rule(s), and optional end time (DTEND) again with or without timezone. These combined allow for the generation of any events between the start and end time, and these will either be as an Absolute time if the applicable timezone is known (so treat as case 1), or Floating events if the timezone is not known (so treat as case 2). If you are using python then the Arrow library is pretty good at generating recurring events.