在说时区问题的时候,估计很多人都很不屑。因为获取时区的方法真的太简单了。尤其是很多面向百度编程的iter。
比如,获取时区的方法一句就能搞定:
String timeZone =“GMT”+String.valueOf(TimeZone.getDefault().getRawOffset() / (3600 *1000));
当时很不屑这个问题的时候。我就知道你肯定会犯的几个你自己都可能不知道的错。就是关于夏时令和冬时令的问题。
那么再说这个问题之前,我们先说说国际上对于时区的规定
时区
1884年在华盛顿召开的国际经度会议(又称国际子午线会议)上,规定将全球划分为24个时区(东、西各12个时区)。
如下图所示:
全球同一时刻不同时区的本地时间不同例如中国时间:10:00 AM
对于美国西部时间:18:00 PM(冬令时)
17:00 PM(夏令时)。
1. GMT VS UTC
GMT 全称 Greenwich Mean Time,中文为格林威治标准时间。
UTC 全称 Universal Time Coordinated, 中文为协调世界时。
GMT和UTC都是代表0零时区的时间,两者相等。UTC是1972年之后引入的概念,是GMT的后继,现广泛应用于科技领域。
2. PST
全球分为24个时区之后,从UTC/GMT 开始往西依次表示为UTC/GMT - 1,-2……,往东表示为UGC/GMT+1,+2……。
除了UTC/GMT之外,还有一个很常见的时区:PST。
PST 全称 Pacific Standard Time,太平洋标准时间,等同于UTC/GMT -8,既西八区,被北美国家使用。
冬令时、夏令时
地球自转方向从西向东,所以东边更早看到新一天的太阳。各地区在时区概念的基础上,时间更接近于太阳时(最简单的理解就是太阳直射时,当地时间基本接近12点)。
昼夜长短会随着四季变换,出于减少能源消耗的目的,提出了冬令时、夏令时的概念。
在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。
冬令时通常代表使用当地的标准时间,夏令时实施期间时钟拨快一小时,相当于时区往前(东)进一个。
每年会对时间进行两次调整,如下图所示:
也就是说,地球上并不是每一天都是24小时的。也有一天23小时或25小时的存在。
夏令时起始和结束的两天,其中开始的一天23小时,结束的一天25小时。
具体好奇的可以进入这个传送门看看究竟。博主在这里就不再具体讲夏令时和冬令时的问题了。小饼干就把项目中遇到的坑跟大家分享一下:
我其中的一个项目主要服务欧美客户,春天,因为时区问题,被报了bug(美国市场部同事报的),我检查了代码,然后没发现有问题,但还是改了。然后同年冬天,再次因为这个问题被报了bug。我很郁闷,这个问题明明解决过,并且验证过的啊。为什么又出现了。然后我始终找不到我具体哪里出问题了。后来,我很奇怪美国时间为什么不对(因为办公室之前所在地之前相差18个小时,后来相差17个小时)。美国人不知道中国时区不分夏令时和冬令时(备注俄罗斯也不再区分夏令时和冬令时,但是目前国际上仍然有超过110个国家和地区区分夏令时和冬令时)。然后我就查阅了资料,明白了夏令时和冬令时的问题。
好了,故事就讲到这里,我们说说怎么解决这个问题吧。我也曾面向百度编程,查阅了这方面的资料,试过其他踩过坑的大佬写的方法,但是最后都不能达到随意切换时区和时令都测试通过的结果。(大家可以自行百度尝试其他方法和各种时区切换和时令切换测试)。
最后只能靠自己了。我回想为什么会出现导致时区的问题,并且一想,不管系统的时间怎么变,他都在相应时区内变化。一旦超过,就自动出现时区也不对了。所以这个问题就非常简单了。只需改一个地方就解决:
public static String getTimeZone() {
String timezone ;
// 这里注释的是之前获取到的时区,但是不分夏令时和冬令时(格林威治时间划分的)
// int _t = TimeZone.getDefault().getRawOffset() / (3600 * 1000);
// 改为如下,获取系统的时间并且计算出时区就可以了
int _t = TimeZone.getDefault().getOffset(System.currentTimeMillis()) / (3600 * 1000);
timezone = String.valueOf(_t);
timezone = "GMT" + timezone;
return timezone;
}
好了,这样就解决了同一个时区,因为夏天和冬天,不在同一个时区的问题。就解决了不管怎么切换时区,都能拿到改时间应该所在的时区的问题了。
更多问题讨论QQ:578161213。