PHP在国内流行度可能不高,看国内的大型虚拟主机提供商提供的主机就可以看出来了,可能很多PHPer把自己的程序放到了国外的服务器上,这时就遇到了一个时间问题,比如戒烟如你现在用的这个,服务器时区是-6,这样就需要对系统时间进行处理,目前在用的SaBlog处理得就不够好,还是自己来研究下吧!
首先值得强调的是,PHP对时间处理功能是比较强的,关键看怎么用。这里探讨的时候认为服务器的时间是没有问题的,仅仅探讨时区问题,以期获得程序最大的可移植性。
最常用的函数:int time (),用于获取当前的UNIX时间戳,经过检测,该函数是不被时区影响的,戒烟如你认为使用该函数获取的时间戳可以直接进数据库,即使进行移植也不会影响使用。
string date ( string format [, int timestamp]),这个函数也很常用,它是受到服务器时区影响的,在手册里讲得也很清楚,这个函数用于“格式化一个本地时间/日期”,也就是说,date()在输出日期时自动在时间戳上加了服务器时差。因此使用该函数格式化时间戳进行输出的时候,既要考虑到服务器时区问题,也要考虑到用户时区问题。我们在客户端输出的时候,对于标准时,需要加上客户端的时差,然后把服务器时差给去掉,即:
- $s = date('Z'); // 获取服务器时差
- $b = 3600 * 8; // 客户端时差,这里是北京时间
- $time = time() + $b - $s; // 计算用于显示的时间戳
- $date = date('Y-m-d H:i:s', $time); // 这就是北京时间了
另一个输出时间的函数array getdate ( [int timestamp])和date()是一样的,输出的也是本地时间,需要参考上面的代码进行校正。
上面是将时间戳格式化后输出,这个是将输入的时间转化成时间戳。int mktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]]),它是受服务器时区影响的,其实就是函数date()的逆运算,假定输入的时间是标准时,转化成时间戳,然后减去服务器的时差。我们在使用时就需要重新加上这个时差,然后减去客户端的时差,才能得到客户端输入时间真正的时间戳。继续上面的代码,即:
- $time = explode(' ',$date); // 分拆日期时间中的空格
- $d = explode('-', $time[0]); // 分拆日期成数组
- $t = explode(':', $time[1]); // 分拆时间成数组
- $newtime = mktime($t[0], $t[1], $t[2], $d[1], $d[2], $d[0]); // 格式化成时间戳
- $newtime = $newtime - $b + $s; // 这才是想要的时间戳
最后两个:
string gmdate ( string format [, int timestamp])
int gmmktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]])
这两个函数直接忽略服务器时区设置,也就是说,上面两段代码中凡是涉及服务器时区的部分都可以删掉,前者输出的时间是该时间戳对应的标准时,后者将输入的时间认定为标准时后转化成时间戳输出。
第一段代码修改后:
- $b = 3600 * 8; // 客户端时差,这里是北京时间
- $time = time() + $b; // 计算用于显示的时间戳
- $date = gmdate('Y-m-d H:i:s', $time); // 这就是北京时间了
第二段代码修改后:
- $time = explode(' ',$date); // 分拆日期时间中的空格
- $d = explode('-', $time[0]); // 分拆日期成数组
- $t = explode(':', $time[1]); // 分拆时间成数组
- $newtime = gmmktime($t[0], $t[1], $t[2], $d[1], $d[2], $d[0]); // 格式化成时间戳
- $newtime = $newtime - $b // 这才是想要的时间戳
最后提醒一下:目前所有的 Windows 系统都不支持负的时间戳。因此合法的年份范围只包括从 1970 到 2038。(这也是PHP手册中的警告)
#1
