简体   繁体   English

MySQL/MariaDB:存储带时区的日期时间

[英]MySQL/MariaDB: Store a datetime WITH timezone

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.据我所知, DATETIME 类型没有时区。

And type TIME is limited from the year 1970 to 2038.类型 TIME 仅限于 1970 年至 2038 年。

I live in a country with a different timezone in summer (CEST) as it is in winter (CET).我住在夏季 (CEST) 和冬季 (CET) 时区不同的国家/地区。 So there is a double hour 3 when we switch from CEST to CET.所以当我们从 CEST 切换到 CET 时,有一个双小时 3。

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.当我无法获得包含时区的日期时间并且我需要区分这个小时 3 时,我别无选择,只能手动处理它。

eg have another column for it or convert any DATETIME into UTC.例如,为其设置另一列或将任何 DATETIME 转换为 UTC。

Is that the only way or did I miss something?这是唯一的方法还是我错过了什么?

You will generally avoid a lot of headaches by storing times in UTC. 通过将时间存储在UTC中,通常可以避免很多麻烦。 Then there's no 'double hour 3', the arrow of time just marches inexorably forward :) 然后就没有“双小时3”,时间之箭无情地向前进:)

I'm writing this answer at 14:27 CEST, which would be stored as 12:27 UTC in a database. 我在CEST 14:27写这个答案,它将以UTC 12:27的形式存储在数据库中。 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). 如果我想以最终用户熟悉的形式显示时间,我希望他们从Olsen数据库中选择一个时区,并使用该时区来找出正确的偏移量(如果需要,可以将时区存储为单独的列以始终显示该区域中的时间)。

See this excellent question/answer for more depth, including lots of links for timezone handling in various languages. 有关更多信息,请参见此出色的问题/答案 ,包括许多用于各种语言的时区处理的链接。

It depends on what you are really doing. 这取决于您的实际工作。

  • An "event" calendar -- The concert starts at 8pm in a particular time zone. “活动”日历-音乐会在特定时区的晚上8点开始。
  • A universal time of when something happened. 发生某事的世界时间。
  • ... (There are about 5 different needs for timezones.) ...(时区大约有5种不同的需求。)

MySQL/MariaDB has only 2: MySQL / MariaDB只有2个:

  • DATETIME -- think of as a picture of a clock. DATETIME想像为时钟的图片。 It's what you see in your timezone. 这就是在时区中看到
  • TIMESTAMP -- think of it as this instance in the universe. TIMESTAMP将其视为Universe中的此实例。 Or think of as being implemented by converting from your timezone to UTC and the UTC value is stored. 或认为是通过从您的时区转换为UTC并存储UTC值来实现的。 (And converted back when you SELECT it.) (并在SELECT它时转换回去。)

If either of those works for you, then use it. 如果这些都适合您,请使用它。 If not, I might suggest storing a TIMESTAMP plus a timezone offset (in minutes). 如果没有,我建议您存储一个TIMESTAMP加上时区偏移量(以分钟为单位)。 All offsets (currently) are (I think) in multiples of minutes. (我认为)所有偏移量都是(以分钟为单位)分钟的倍数。 (Netherlands once had an offset that went down to the second.) Most countries are some multiple of an hour away from UTC. (荷兰以前的补偿金额下降到了第二位。)大多数国家/地区距离UTC大约一个小时的路程。 India is the biggest country with a half-hour offset. 印度是最大的国家,每半小时补班一次。

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.通常(也是最常见的用例)存储带有时区的时间戳,最好是 UTC,以节省进出转换和处理比较中的时区差异。 This should covers all historical and fixed point in time events (such as logs, or "event occured at", "item was changed/created at").这应涵盖所有历史和固定时间点事件(例如日志或“事件发生于”、“项目更改/创建于”)。 ie. IE。 the TIMEZONE typeTIMEZONE类型

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.将其与 IANA 时区字符串一起存储,不要转换为 UTC。 Timezone changes will not affect the event time unless the timezone was deleted (unlikely to happen).除非删除时区(不太可能发生),否则时区更改不会影响事件时间。 ie. IE。 DATETIME and a second field of type VARCHAR() to store the timezone such as Pacific/Auckland , or Australia/Sydney . DATETIMEVARCHAR()类型的第二个字段来存储时区,例如Pacific/AucklandAustralia/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.它是否是未来(可能重复发生)事件的浮动时间,例如“从中午开始,每天午餐时间为 1 小时”,在将其解决为具有时区之前,无法将事件固定到固定时间点。 So if you need to store these, then store them as DATETIME .因此,如果您需要存储这些,则将它们存储为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.不要在未来存储每个事件的时间戳,使用 RFC5545 中提供的逻辑存储重复规则,以便您可以轻松生成未来事件。 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.这意味着在有或没有时区的情况下存储重复事件的开始时间 (DTSTART)、重复规则,以及在有或没有时区的情况下再次存储可选的结束时间 (DTEND)。 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).这些组合允许在开始时间和结束时间之间生成任何事件,如果适用的时区已知,这些事件将作为绝对时间(因此视为情况 1),或者如果时区未知则为浮动事件(因此视为情况 2)。 If you are using python then the Arrow library is pretty good at generating recurring events.如果您使用的是python ,那么Arrow库非常擅长生成重复事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM