【发布时间】:2013-11-19 12:39:03
【问题描述】:
我有数千张在坦桑尼亚拍摄的照片,我想将每张照片的拍摄日期和时间存储在 MySQL 数据库中。但是,服务器位于美国,当我尝试存储在春季夏令时(在美国)的“无效”小时内的坦桑尼亚日期时间时遇到了问题。坦桑尼亚不做夏令时,所以时间是一个实际有效的时间。
其他复杂情况是,来自许多不同时区的合作者需要访问存储在数据库中的日期时间值。我希望他们始终以坦桑尼亚时间出现,而不是各种合作者所在的当地时间。
我不愿意设置会话时间,因为我知道如果有人有时忘记设置会话时间并弄错时间,就会出现问题。而且我无权更改服务器的任何内容。
我读过: Daylight saving time and time zone best practices 和 MySQL datetime fields and daylight savings time -- how do I reference the "extra" hour? 和 Storing datetime as UTC in PHP/MySQL
但它们似乎都没有解决我的特殊问题。我不是 SQL 专家。有没有办法在设置 DATETIME 时指定时区?我一个都没见过。否则,非常感谢任何有关如何解决此问题的建议。
编辑: 这是我遇到的问题的一个例子。我发送命令:
INSERT INTO Images (CaptureEvent, SequenceNum, PathFilename, TimestampJPG)
VALUES (122,1,"S2/B04/B04_R1/IMAG0148.JPG","2011-03-13 02:49:10")
我得到了错误:
Error 1292: Incorrect datetime value: '2011-03-13 02:49:10' for column 'TimestampJPG'
此日期和时间存在于坦桑尼亚,但不存在于数据库所在的美国。
【问题讨论】:
-
您不应该将时区信息存储在数据库中。将所有日期/时间数据存储为 UTC,并始终在应用层进行时区偏移调整。
-
@MarcellFülöp:我一直看到人们说“将其存储为 UTC”,但我不明白这是什么意思。如何将日期时间存储为“UTC”?据我所知,我所能做的就是插入格式为 YYYY-MM-DD HH:MM:SS 的内容。我在哪里告诉数据库它是 UTC?
-
你没有。默认情况下,MySQL 将在内部使用系统时区,但可以为 MySQL 服务器全局甚至每个事务定义不同的时区。插入日期时,无法在 MySQL 中定义时区和日期字符串。像“2013-11-10 00:00”这样的日期是指自纪元以来的时间点。您存储它并且您知道您的服务器所在的时区。然后当您检索它时,您可以进行必要的调整以将该日期从服务器的时区转换为客户端的时区。
-
@marekful 不,这取决于。我想过滤掉黎明时分拍摄的照片,在这种情况下,UTC 将无济于事。我想同时保存 UTC 时间戳和时区偏移量。
-
IMO 和许多经验丰富的工程师遵循的最佳实践仍然是将所有日期/时间值存储为 UTC(又名 Zulu)。无论物理位置如何,都将数据库服务器配置为 UTC。然后,在这种特殊情况下,您想要做的是知道您想要找到与坦桑尼亚的黎明相对应的一天中的时间。因此,您在程序代码中添加逻辑。使用坦桑尼亚的时区创建一个时区实例,并过滤通过它从数据库中获取的所有日期/时间值。它将完成其余的工作并代表坦桑尼亚时间的所有价值观。它还将处理 DST。