1. UTC和GMT到底是什么
  gmt和utc都是标准时间。
  GMT是比较古老的时间较量标准,根据地球公转自转计算时间。UTC则是根据原子钟来计算时间,现在基本都用UTC时间。
时区的设置之前研究过https://java-er.com/blog/php-utc-time-default-set/,本文主要研究夏令时2. 夏令时计算有几个坑,需注意:

1) 时间服务器返回的时间为1900距今的秒数,而我们需要借助unix时间函数转为可读的时间 ,因此需要先把这个时间减去70年(2208988800s)。

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

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

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

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

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

date_default_timezone_set("Etc/GMT-8");

代表+8 区
我是美国人在美国,那么程序设置为美国时区

date_default_timezone_set("Etc/GMT+5");

代表-5区

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

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

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

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

5. 夏令时的秘密

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()-2*30*24*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()-2*30*24*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