各种时间格式(UTC、GMT等)及夏令时和冬令时

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种时间格式(UTC、GMT等)及夏令时和冬令时相关的知识,希望对你有一定的参考价值。

参考技术A

参考资料:
一些时间的概念与区分(UTC、GMT、LT、TAI等)
夏令时和冬令时之趣事

UT(Universal Time) - 世界时:最老

TAI(international atomic time) - 国际原子时:最准

GMT(Greenwich Mean Time) - 格林尼治标准时间,格林威治平均时间:根据本初子午线太阳时再根据地球特点等因素调整的时间

UTC(Universal Time Coordinated) - 协调世界时:在GMT的基础上再根据TAI调整得到的时间

我们一般认为GMT和UTC是一样的,都与英国伦敦的本地时相同。

LT(LocalTime) - 本地时间

所在时区的时间。UTC或GMT与LT如下的换算关系:LT=UTC+时区差 ;
东区是加相应的时区差,西区是减时区差。如北京是东八区,则北京时间=UTC+8.

中国和英国的时差为多少:
简单粗暴地给大家举例解释:夏令时,中国和英国的时间相差7个小时,如北京时间为早上10:00,伦敦时间为凌晨3:00;冬令时,中国和英国时差为8个小时,如北京时间为早上10:00,英国时间为凌晨2:00。如此简单的加减,你会换算了吗?

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

  • 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/

    以上是关于各种时间格式(UTC、GMT等)及夏令时和冬令时的主要内容,如果未能解决你的问题,请参考以下文章

    utc时间21是北京时间多少

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

    SQL Server 2008 函数将 GMT 时间转换为 AEST 并采用夏令时

    MySQL默认时间格式是UTC还是GMT?

    亚马逊夏令时可靠性

    数据库中的 GMT 时间