为了我的目的,我已经弄清楚了。我会总结一下我学到的东西(抱歉,这些笔记很冗长;它们对于我未来的推荐和其他任何东西一样重要)。
与我在之前的评论中所说的相反,DATETIME 和 TIMESTAMP 字段的行为确实不同。TIMESTAMP 字段(如文档所示)采用“YYYY-MM-DD hh:mm:ss”格式发送的任何内容,并将其从当前时区转换为 UTC 时间。每当您检索数据时,相反的情况就会透明地发生。DATETIME 字段不进行此转换。他们拿走你寄给他们的任何东西,然后直接存储。
DATETIME 和 TIMESTAMP 字段类型都不能准确地将数据存储在遵守 DST 的时区中。如果您存储“2009-11-01 01:30:00”,则这些字段无法区分您想要的凌晨 1:30 的哪个版本——-04:00 或 -05:00 版本。
好的,所以我们必须将数据存储在非 DST 时区(例如 UTC)中。由于我将解释的原因,TIMESTAMP 字段无法准确处理此数据:如果您的系统设置为 DST 时区,那么您放入 TIMESTAMP 的内容可能不是您返回的内容。即使您向其发送已转换为 UTC 的数据,它仍会假定数据位于您的本地时区并再次转换为 UTC。当您的本地时区遵守 DST 时(因为“2009-11-01 01:30:00”映射到 2 个不同的可能时间),此 TIMESTAMP 强制执行的本地到 UTC-回到本地往返是有损的。
使用 DATETIME,您可以将数据存储在您想要的任何时区,并确信无论您发送什么数据,您都会取回(您不会被迫进行 TIMESTAMP 字段强加给您的有损往返转换)。因此,解决方案是使用 DATETIME 字段,然后在保存到字段之前将系统时区转换为您想要保存的任何非 DST 区域(我认为 UTC 可能是最好的选择)。这允许您将转换逻辑构建到脚本语言中,以便您可以显式保存“2009-11-01 01:30:00 -04:00”或“2009-11-01 01:30”的 UTC 等效值: 00 -05:00”。
另一个需要注意的重要事项是,如果您将日期存储在 DST TZ 中,MySQL 的日期/时间数学函数在 DST 边界附近无法正常工作。因此,更有理由保存 UTC。
简而言之,我现在这样做:
从数据库中检索数据时:
将数据库中的数据显式解释为 MySQL 之外的 UTC,以获得准确的 Unix 时间戳。为此,我使用 PHP 的 strtotime() 函数或其 DateTime 类。它不能在 MySQL 内部使用 MySQL 的 CONVERT_TZ() 或 UNIX_TIMESTAMP() 函数可靠地完成,因为 CONVERT_TZ 只会输出存在歧义问题的 'YYYY-MM-DD hh:mm:ss' 值,并且 UNIX_TIMESTAMP() 假定它的输入在系统时区中,而不是数据实际存储在 (UTC) 中的时区。
将数据存储到数据库时:
将您的日期转换为您希望在 MySQL 之外的精确 UTC 时间。例如:使用 PHP 的 DateTime 类,您可以指定“2009-11-01 1:30:00 EST”与“2009-11-01 1:30:00 EDT”不同,然后将其转换为 UTC 并保存正确的 UTC 时间到您的 DATETIME 字段。
呸。非常感谢大家的投入和帮助。希望这可以为其他人节省一些麻烦。
顺便说一句,我在 MySQL 5.0.22 和 5.0.27 上看到了这个