MySQL 时区相关问题
昨晚,是一个愉快的、有意义的、充实的夜晚;昨晚,对于我的一生来说都是十分重要的一晚;昨晚,虽然是夜晚,但却是明媚、阳光的一晚。这一切,都是因为有了你,feelinglucky。
lucky 兄已在 gracecode.com 上面概述了昨夜我们之间发生的故事,这里做一个全面的流水记录。让花花草草都来羡慕我们这天上的一对、地上的一双吧。
昨晚接到一个工单,要给一个客户对帐。我和同事 Henry Xu 分别在 MySQL 和 SQL Server 做了一次查询,结果显示的时间正好相差八小时。Henry 说:“肯定是你 MySQL 的时区有问题,慢了八个小时”。我看看是啊,想起 lucky 的一篇文章,于是到 phpmyadmin 中查询:
SELECT UNIX_TIMESTAMP();
结果显示的时间戳,通过 PHP 的 date 函数转换出来,确实与那时的北京时间相差八个小时。我继续在 phpmyadmin 中查询:
SELECT NOW();
这次结果居然是正确的。暂时糊涂了,看看时间,北京时间21点多,一通电话直接找到 lucky。这里插播一则广告,本人专业出售 lucky 手机号码,有需要的 MM 请直接在下面留言,谢谢。
我们一边谈一边查资料,后来在 MySQL 手册上看到:UNIX_TIMESTAMP() 是返回世界协调时 UTC 的时间,不参照本机系统时区。网上也有一种说法:使用 UNIX_TIMESTAMP() 函数是获取不到正确的当地时间的时间戳,除非当前系统时区就在 0 时区。后来 lucky 提示使用 CURRENT_TIMESTAMP() 代替,但是由于我目前的数据库设计习惯,暂时不能接收非时间戳的值。
后面 lucky 就在说服我使用 datetime 的数据库类型。我一边写了一个小脚本:
<?php
并把这个脚本放到服务器上跑了一下,结果发现两行输出居然是一样的。我纳闷,然后将脚本复制到 Zend Studio 里面,F5…… My god,原来是 Zend Studio 的问题……
$a = 0000000000; //从 phpmyadmin 中查询 SELECT UNIX_TIMESTAMP(); 后复制过来的 10 位数字
$b = time();
echo date('Y-m-d H:i:s', $a) . "<br />" . date('Y-m-d H:i:s', $b);
?>
下面复制一些与 lucky 的交流记录,谨作这一夜的纪念。
feelinglucky: http://www.modwest.com/help/kb6-256.html
feelinglucky: -_- 我搜索 “mysql 时区”竟然都是我的文章……
wiLdGoose: 是的
feelinglucky: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html
NOW 是正确的是吧?
用 CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP 看看
Synonyms for NOW()
wiLdGoose: ..........
feelinglucky: CURRENT_TIMESTAMP and CURRENT_TIMESTAMP() are synonyms for NOW().
feelinglucky: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_current-date
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_current-timestamp
wiLdGoose: 我知道的
他和 NOW() 一样的
我不要字符串的
我要整数
feelinglucky: Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. The value is expressed in the current time zone.
这个是 NOW() 的,注意最后一句
wiLdGoose: yep
NOW 是对的啊
那 UNIX_TIMESTAMP() 就乱来了?
不根据当前时区了?
feelinglucky: UTC_TIMESTAMP()(v4.1.1) Return the current UTC date and time
是 return UTC 时间
当前 UTC 时间
feelinglucky: 应该用 UNIX_TIMESTAMP
wiLdGoose: http://www.linuxrpm.com/forums/viewtopic.php?t=232
看这个
他的意思是放弃 unix_timestamp
feelinglucky: 这种说法是不对的
wiLdGoose: ?
feelinglucky: 返回 UTC 时间是有用处的,不能更改的
打个比方,两台服务器之间如果跨时区的话,时间保证会统一到 UTC 时间的
CCTV 不是经常说的嘛“格林威治时间 XXX”嫦娥一号升空
wiLdGoose: 是不是 unix_timestamp() 返回的时间和 now() 就是不一样的
先不论格式
feelinglucky: 用 CURRENT_TIMESTAMP 不行吗
wiLdGoose: 那还是一样要改代码
feelinglucky: 至少可以确定它是根据时区选项来的
wiLdGoose: 再说 CURRENT_TIMESTAMP 返回的是 datetime 格式
feelinglucky: :( 搞不懂为什么一定要时间戳
wiLdGoose: i like it
:D
feelinglucky: 你不会吧数据库都用时间戳设计的吧。。。
wiLdGoose: 是的
feelinglucky: 然后用 INT(10) ?
wiLdGoose: 是啊
你喜欢 datetime?
feelinglucky: 天啊
:(
wiLdGoose: 来吧 说服我
我听着
feelinglucky: 这样快不了多少的
直观方面先不说,这个都清楚
然后就是计算问题
比如获得最近一周的所有数据,你怎么办?
在一个表里面
wiLdGoose: 你是不是想说, 用 datetime 类型的数据, 可以直接用mysql的函数比较日期
feelinglucky: 或者获得星期一我要的所有打卡记录
wiLdGoose: 时间戳也有时间戳的好处嘛
datetime的话, 遇到特殊情况, 还是要 strtotime
多不完美
feelinglucky: 如果按照你的,保证会有一个 xxxx < monday and xxxx > monday 这样的 WHERE 条件
想象一下,这个不是日期的比较哦,是整形对整形的比较
wiLdGoose: 是的
feelinglucky: PHP 方面你首先要知道星期一的时间戳,然后再让数据库 WHERE 计算
wiLdGoose: 数字与数字比较, 不是比字符串与字符串比较方便么?
feelinglucky: 相比 MYSQL 一条语句就 OK,哪个完美呢
时间类型不是字符串类型 :(
时间对于用户来看很直观,会“误认为”是字符串,但是在 mysql 内部存储还是长整型的
feelinglucky: 这个亲爱的可以 Google 一下
我以前也这样认为的,和你的做法一样,后来看了 wordpress 的数据库设计方面的一篇文章,谈到日期的数据库设计,才转变回观念来的
退一步讲,就算时间计算比整形的要低,但是毕竟用这个能方便很多
wiLdGoose: 我空了去研究一下, 先去改代码了
feelinglucky: OK,长篇大论留到 Blog 让亲爱的欣赏 :D
wiLdGoose: 好的.
Thx.
wiLdGoose: 我晕死了
feelinglucky: ?
wiLdGoose: 我发现我用php写一个 echo time() 输出都错的
但是php配置文件已经修改的了啊.
[Date]
; Defines the default timezone used by the date functions
date.timezone = PRC
feelinglucky: ?!
ft
wiLdGoose: 我吐血了, 刚才写了一个 test.php
你看看 www.xxxx.com/test.php
feelinglucky: 对的啊
wiLdGoose: 我被忽悠了
feelinglucky: ?
wiLdGoose: 我电话你, ok?
feelinglucky: ok
关于坚持使用时间戳还是转投 datetime 的环抱,我目前还没有想好。花点时间研究一下吧。
另外有一则好消息吧,Perl 5.10.0 终于释出了。
那天群发SMS好像把某人给漏了。号码被我复制到txt中然后忘了存进手机了,不然的话,一定一堆AD发给他。
通过智能ABC输入法大概知道但不确切,以致于我不知道在手机中该以什么作为显示名。或者直接是LJF
OK,任务完成。睡觉
其实,whois上面可以看到很多隐私.
所以enom有提供域名whois保护。不过就是贵了点。一年$10
whois privacy protect 不光 enom 有.
其实 $10 是很划算的价格.
唉,回家与世隔绝了,报到一下
域名多了就不好说了。。
看了半天,还是不明白,有机会与作者讨论,我的msn:[email protected];
QQ:75320364
我个人觉得还是多看手册.即便有时候可能觉得手册中说的不够详细.感谢浪子兄的链接.我也已做好链接.