【发布时间】:2011-02-28 07:13:03
【问题描述】:
我有一个应用程序当前将时间戳存储在 MySQL DATETIME 和 TIMESTAMP 值中。但是,应用程序需要能够接受来自多个时区的用户的数据,并在其他用户的时区显示时间戳。因此,这就是我计划修改申请的方式;如有任何改进方法的建议,我将不胜感激。
数据库修改
- 所有 TIMESTAMP 都将转换为 DATETIME 值;这是为了确保方法的一致性并避免让 MySQL 尝试做聪明的事情并转换时区(我想在 PHP 中保留转换,因为它涉及对应用程序的较少修改,并且当我最终设法逃离 MySQL)。
- 将调整所有 DATETIME 值以将其转换为 UTC 时间(目前全部为澳大利亚东部标准时间)
查询修改
- 在查询、触发器、函数等中使用 NOW() 替换为 UTC_TIMESTAMP()。
应用修改
- 应用程序必须存储时区和首选日期格式(例如美国与世界其他地区)
- 所有时间戳都会根据用户设置进行转换后显示
- 所有输入时间戳在输入前都会根据用户设置转换为UTC格式
补充说明
- 转换格式将在应用程序级别完成,主要原因有几个
- 转换时区的方法因数据库而异,因此将其交给那里将是不可移植的(我真的希望在不久的将来能够从 MySQL 迁移)。
- MySQL TIMESTAMP 的允许日期范围有限(~1970 到~2038)
- MySQL TIMESTAMP 具有其他不良属性,包括奇怪的自动更新行为(如果不小心禁用的话)和对服务器区域设置的敏感性(我怀疑当我在今年晚些时候迁移到 Amazon 时可能会搞砸这些)。
- 选择更改所有当前日期时间值并使用 UTC_TIMESTAMP() 代替 NOW() 是为了避免服务器/连接时区设置出现任何问题,这将修改 NOW() 但不理会 UTC_TIMESTAMP();请参阅下面的示例。
UTC_TIMESTAMP() 与 NOW() 的示例
mysql> set time_zone = 'Australia/Canberra';
Query OK, 0 rows affected (0.06 sec)
mysql> select now(), utc_timestamp();
+---------------------+---------------------+
| now() | utc_timestamp() |
+---------------------+---------------------+
| 2010-06-06 14:31:36 | 2010-06-06 04:31:36 |
+---------------------+---------------------+
1 row in set (0.00 sec)
mysql> set time_zone = 'America/Los_Angeles';
Query OK, 0 rows affected (0.00 sec)
mysql> select now(), utc_timestamp();
+---------------------+---------------------+
| now() | utc_timestamp() |
+---------------------+---------------------+
| 2010-06-05 21:31:43 | 2010-06-06 04:31:43 |
+---------------------+---------------------+
1 row in set (0.00 sec)
这里有什么我遗漏的吗,或者有人对这种方法有更好的建议吗?
【问题讨论】: