PHP中的时区问题


前言

在做一些海外项目的时候,常常会遇到时间混乱的问题,因为每个地区的时区不同,但是系统会默认服务器所在地的时间,所以当我们的系统处理当地的业务时,就会有时间误差的问题。


一、时区是什么?

全球总共有24个时区,用UTC表示,每个时区的中央经线上的时间就是这个时区内统一采用的时间,称为区时,相邻两个时区的时间相差1小时

以UTC为参照物计算时区
但随着UTC取代GMT成为世界标准时后,时区的计算开始使用UTC作为标准。UTC+8代表东八区,UTC-11代表西十一区。
不过随着精度需求的提升,按大时区计算已经不能满足需求,0.5个时区也被普遍使用,比如UTC+7.5。

在PHP中,我们可以采用这种方式来切换时区。比如:

date_default_timezone_set('UTC');echo date('Y-m-d H:i:s'); // 获取的是0时区时间

二、时间戳是什么?

是计算机世界通用的一种约定。时间戳是指格林尼治时间(GMT)1970年01月01日00时00分00秒到当前时间的总秒数。按道理来说,全世界所有的电脑和服务器的时间戳都是一致的,跟时区无关,实际上可能并不完全相同,但相差也是几豪秒,可以完全忽略不计,影响不大。

三、php中的时区问题

1、我们在使用php的data函数去对时间戳进行转换的时候,它会根据服务器所处在的地区的时区进行转换,这就会遇到问题,比如说:

一款针对海外酒店销售的app,它是由中国团队进行运营的,当海外酒店供应商给到该运营团队一些酒店,希望通过app销售他们的酒店,那么该运营团队对这些酒店进行录入工作,这时候存进去系统的可预定时间实际上是中国时间,系统里存起来的是中国时间转换后的时间戳,并不是其当地时间转换后的时间。这就可能导致这些酒店的可入住时间和当地时间是有偏差的。

四、如何解决呢?

1、我们把服务器的php.ini配置文件改为当地的时区。

date.timezone = PRC

设置完以后,我们使用strtotime和data函数的时候就会自动根据当地的时区进行时间的转换。
但酱汁做是有弊端的,当我们的产品面向许多地区的时候,有多个时区的情况下,不可能说单单改一个配置文件就能解决问题。

2、在php代码开头,可以使用date_default_timezone_set函数来临时修改一些php的默认配置:

date_default_timezone_set('Asia/Shanghai');

设置完以后,我们在这个php文件里面使用strtotime和data函数的时候就会自动根据当地的时区进行时间的转换。

3、当你在输出一个日期的时候,如果使用date,就是可变的,但如果使用gmdate()就是不可变的,gmdate()永远把时区当做是UTC+0,即使你通过前面三种方法临时修改了时区,也不会影响gmdate的输出结果,而这个时候,其实你又知道你的访客所在的时区,所以,你可以自己计算一下:

gmdate('Y-m-d H:i:s',time() + 8*3600);

建议:存储在数据库的时间我们以时间戳的方式进行存取,读取的时候再对其进行转换即可。

附加:
使用当地日期转换为当地时间戳的写法:
strtotime(‘2020-09-18T16:35:21+00:00’); //获取0时区时间的时间戳
strtotime(‘2020-09-18T16:35:21+08:00’); //获取8时区时间的时间戳


总结

为了解决这个时区的问题,我们最好把全球的时区库存在我们的数据库中或者配置文件中,当需要调用的时候可以方便进行调用。针对跨多个时区的项目,我们可以根据我们本身存储的时区库,对负责不同逻辑区域的代码进行时区的设置即可。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值