MySQL 有两种专门用于存储日期和时间值的数据类型 - DATETIME
和 TIMESTAMP
。这两种类型都没有存储时区信息,并且都有不同的规则。
DATETIME
列将存储插入查询中提供的确切日期和时间值。 (没有转换,也没有时区可供选择)
TIMESTAMP
列会将插入时提供的日期和时间值从插入时连接的时区转换为 UTC。在检索时,它会将存储的日期和时间值从 UTC 转换为检索连接的时区。
两个连接的时区可以根据这些 rules 显式或隐式设置。
现在,在回答我的问题之前,让我们先看看涉及夏令时的处理日期和时间的一些细微差别。总结另一个 Stack Overflow question 的答案以及我从 MySQL documentation 中了解的关于日期/时间的内容:
- 当使用
DATETIME
列并明确指定一个值(即/2009-11-01 01:30:00
)时,该值可能不明确。DATETIME
不执行对话,只是存储这个确切的日期/时间。假设我在纽约(遵循夏令时)。在插入和检索时,我都无法指示/知道此值是指有夏令时时刻 (UTC-4) 的凌晨 1:30 还是无夏令时时刻 (UTC-5) 的凌晨 1:30 ). - 将
DATETIME
列与NOW()
一起使用时,NOW()
计算为查询执行开始时的日期和时间值(即/2009-11-01 01:30:00
),并且该值不经任何转换就插入到DATETIME
字段中,从而导致同样的歧义如上所述。 - 当使用
TIMESTAMP
列并明确指定一个值(即/2009-11-01 01:30:00
)时,我再次遇到与上述相同的问题。无法具体说明,也无法知道我指的是哪个凌晨 1:30。
现在,这是我的问题:
如果 MySQL 连接设置为包含夏令时的时区(例如 America/New York
),我能否确定将 NOW()
插入 TIMESTAMP
列将导致存储正确的 UTC 日期和时间值? UTC 当然不遵守夏令时,因此 1:30am New York timezone with-daylight-savings moment 的 UTC 时间与 1:30AM New York 的 UTC 时间不同没有夏令时的时区。
更具体地说:当我从 TIMESTAMP
列插入/选择时,连接时区的 UTC 偏移量 是用于执行到 UTC/从 UTC 转换的查询执行?回到我的例子,在有夏令时的凌晨 1:30(America\New York
时区)我在 UTC-4,在没有夏令时的凌晨 1:30(America\New York
时区)我在 UTC- 5 - 所以在这两个时刻,当我显式插入 TIMESTAMP
或使用 2009-11-01 01:30:00
隐式插入相同的值时,是否会将不同的值存储在 NOW()
字段中?最后,如果我在跨越这两个时刻的单个 MySQL 连接中,并且我执行两个查询(一个在第一个时刻,一个单独的在第二个时刻),两个查询都会导致正确的(不同的)UTC 值要存储吗?
最佳答案
您可能希望将此用于服务器:
mysql> SHOW VARIABLES LIKE '%zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | UTC | -- Comes from OS
| time_zone | SYSTEM | -- Probably the 'right' setting
+------------------+--------+
使用这些设置,SELECT NOW()
将提供 UTC 时间,而不是本地时间。
对于您的个人计算机,最好让 system_time_zone
等于 Pacific Daylight Time
(或其他任何时间),以反射(reflect)您当前的位置。
INSERTing
或 SELECTing
DATE
或 DATETIME
时,没有 转换发生。把它想象成时钟的图片。
对于 TIMESTAMP
,无论你给它什么,它都会与 UTC 相互转换。也就是说,表中存储的位是 UTC,但您看不到;您只会看到基于上述两个设置的转换后的日期和时间。
我建议获得答案的最佳方法是创建一个包含DATETIME
和TIMESTAMP
的表,设置这两个设置,然后查看存储时会发生什么.然后更改设置并执行 SELECT
。
关于mysql - 在 MySQL 中使用 NOW() 时,我可以确定正确的 UTC 值将存储在 TIMESTAMP 列中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43773410/