我已经明白了我的目的。 我会总结一下我所学到的东西(对不起,这些笔记是冗长的;对于我以后的转介来说,它们和其他东西一样)。
与我之前的评论中所说的相反,DATETIME和TIMESTAMP字段的行为有所不同。 TIMESTAMP字段(如文档所示)以“YYYY-MM-DD hh:mm:ss”格式发送它们,并将其从当前时区转换为UTC时间。 只要您检索数据,反向就会透明地发生。 DATETIME字段不会进行此转换。 他们把你发送给他们的任何东西直接存储起来。
DATETIME和TIMESTAMP字段types都不能准确地将数据存储在观察DST的时区中 。 如果您存储“2009-11-01 01:30:00”,则无法区分哪个版本是您想要的上午1:30,即-04:00或-05:00版本。
好的,所以我们必须将数据存储在非DST时区(如UTC)。 TIMESTAMP字段无法正确处理这些数据,原因我会解释:如果您的系统设置为DST时区,那么您input到TIMESTAMP中的内容可能不会是您返回的内容。 即使您发送的数据已经转换为UTC,它仍然会假设您的本地时区中的数据,然后再转换为UTC。 由于“2009-11-01 01:30:00”映射到2个不同的可能时间,因此当您的本地时区观察DST时,此TIMESTAMP强制执行的本地到UTC返回到本地往返是有损的。
使用DATETIME,您可以将数据存储在任何您想要的时区,并确信您将返回任何您发送的数据(您不必被迫进入TIMESTAMP字段强加于您的有损往返转换)。 所以解决scheme是使用DATETIME字段,并在保存到字段之前,从您的系统时区转换到任何非DST区域,你想保存它(我认为UTC可能是最好的select)。 这允许您将转换逻辑构build到您的脚本语言中,以便您可以明确地保存“2009-11-01 01:30:00 -04:00”或“2009-11-01 01:30: 00 -05:00“。
另外需要注意的是,如果将date存储在DST TZ中,则MySQL的date/时间math函数在DST边界附近无法正常工作。 所以所有更多的理由保存在UTC。
简而言之,我现在这样做:
从数据库中检索数据时:
为了得到一个精确的Unix时间戳,在MySQL之外明确地解释数据库中的数据为UTC。 我使用PHP的strtotime()函数或它的DateTime类。 使用MySQL的CONVERT_TZ()或UNIX_TIMESTAMP()函数不能在MySQL内部可靠地完成这个工作,因为CONVERT_TZ只会输出一个受到多义性问题困扰的'YYYY-MM-DD hh:mm:ss'值,而UNIX_TIMESTAMPinput在系统时区中,而不是数据实际存储在(UTC)中的时区。
将数据存储到数据库时:
把你的date转换成MySQL以外你想要的精确的UTC时间。 例如:使用PHP的DateTime类,您可以从“2009-11-01 1:30:00 EDT”中明确指定“2009-11-01 1:30:00 EST”,然后将其转换为UTC并保存正确的UTC时间到您的DATETIME字段。
唷。 非常感谢大家的意见和帮助。 希望这可以帮助别人解决一些头痛的问题。
顺便说一句,我看到这在MySQL 5.0.22和5.0.27