程序里的国际时区和夏令时

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序里的国际时区和夏令时相关的知识,希望对你有一定的参考价值。

  • UTC和GMT到底是什么
      gmt和utc都是标准时间。
      GMT是比较古老的时间较量标准,根据地球公转自转计算时间。UTC则是根据原子钟来计算时间,现在基本都用UTC时间。
    时区的设置之前研究过https://java-er.com/blog/php-utc-time-default-set/,本文主要研究夏令时
  • 夏令时计算有几个坑,需注意:
  • 1) 时间服务器返回的时间为1900距今的秒数,而我们需要借助unix时间函数转为可读的时间 ,因此需要先把这个时间减去70年(2208988800s)。

    2) 夏令时的开始结束时间使用的是时区转化后的当地时间,因此时间服务器获取到的UTC时间需要转为本地时间,才能进行时间是否在夏令时区间的判断。

    3) 美国的夏令时,从每年3月第2个星期天凌晨开始,到每年11月第1个星期天凌晨结束。以2017年为例,美国2017年夏令时从3月12日开始,到11月5日结束。

    需要注意的是,美国有部分领土不实行夏令时,其中包括:亚利桑那州 (纳瓦霍人保留地除外)、夏威夷、美属萨摩亚、关岛、波多黎各、美属维京群岛。

    1. 数据库存储秒数的意义
      php的time() 返回1970年 0点到现在的秒数 java里也有。 这个秒数不随我们设置服务器时区而改变
      所以存储要存1501829643 这个玩意,而不是2020-02-01 03:40:58

    2. 程序里时区设置的意义
      当我们弄清楚存储了一个固定的值,那么时区只是展示问题。
      我是中国人在中国,那么程序设置为中国时区

    date_default_timezone_set("Etc/GMT-8");
    代表+8 区
    我是美国人在美国,那么程序设置为美国时区

    date_default_timezone_set("Etc/GMT+5");
    代表-5区

    为啥是反的,有人在官方聊过这个话题。

    http://www.php.net/manual/en/timezones.others.php
    The plus and minus signs (+/-) are not intuitive. For example,

    “Etc/GMT-10” actually refers to the timezone “(GMT+10:00)
    Canberra,Sydney,Melbourne”.

    程序的时区设计仅仅为了展示给客户看。

    1. 夏令时的秘密

    date_default_timezone_set("America/New_York");
    $time1 = date("Y-m-d H:i:s");
    $times1 = strtotime($time1);
    echo "纽约时区:".$time1." - ".$times1."<br>";
    echo "该时区使用夏令时:".date(‘I‘, time()).‘<hr />‘;

    $time = time()-23024*3600;//推算到1月
    $stime = strftime( "%Y-%m-%d %H:%M:%S" ,$time)."<br>";
    echo "60天前今天现在时间:".$stime;
    echo "该时区使用夏令时:".date(‘I‘, time()).‘<hr />‘;

    echo "<hr />";

    date_default_timezone_set("ETC/GMT+4");
    $time1 = date("Y-m-d H:i:s");
    $times1 = strtotime($time1);
    echo "GMT+4:".$time1." - ".$times1."<br>";

    echo "该时区使用夏令时:".date(‘I‘, time()).‘<hr />‘;

    $time = time()-23024*3600;//推算到1月
    $stime = strftime( "%Y-%m-%d %H:%M:%S" ,$time)."<br>";
    echo "60天前今天现在时间:".$stime;
    echo "该时区使用夏令时:".date(‘I‘, time()).‘<hr />‘;

    echo "<hr />";
    输出

    纽约时区:2020-03-30 03:31:27 - 1585553487
    该时区使用夏令时:1
    60天前今天现在时间:2020-01-30 02:31:27
    该时区使用夏令时:1
    GMT+4:2020-03-30 03:31:27 - 1585553487
    该时区使用夏令时:0
    60天前今天现在时间:2020-01-30 03:31:27
    该时区使用夏令时:0
    date_default_timezone_set("America/New_York");
    这个时区的设置会因为夏令时的原因,导致在冬季时间不一样

    date_default_timezone_set("ETC/GMT+4");
    这种设置模式,也代表了纽约,但是在时间不受到夏令时的影响而变化。

    结论:
    1.当为了给客户(纽约人)看时间,应采用America/New_York,

    2.当计算机为了跑一天的数据,比如今天卖了多少货物,应该用ETC/GMT+4 固定时间。不然那错开的1小时,我们计算给前一天,还是后一天,感觉都不太适合

    额外的小研究:

    date_default_timezone_set("UTC");
    这个UTC 好像是个什么标准玩意,当设置UTC+4 UTC-8的时候,程序输出时间没有改变,所以大家设置时区用ETC/GMT才能+4 -8

    https://java-er.com/blog/time-zone-summer-day/

    以上是关于程序里的国际时区和夏令时的主要内容,如果未能解决你的问题,请参考以下文章

    时区转换和夏令时

    如何在android中处理时区和夏令时?

    在 Javascript 中使用时区和夏令时

    UTC 时间、时区、夏令时和夏令时切换日期

    PHP 时区问题 |英国夏令时和格林威治标准时间

    将日期字符串解析为某个时区(支持夏令时)