17

一天有24个小时?别开玩笑了!

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzA4MTc4NTUxNQ%3D%3D&%3Bmid=2650520928&%3Bidx=1&%3Bsn=90a2fd0f4644d53785d782517781476a
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

e6JBVrU.gif

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

今天清理邮件,发现这样一条垃圾信息。虽然美股最近的表现很暴躁,但我没有银子花在这无聊的事情上。我有一笔钱,蹲在A股的一只退市股上。由于亏的太多,所以现在只剩下梦想。

u6rIRff.png!web

这条信息让我感兴趣的是, 夏令时 。我曾从很多地方看到过这个词,它总让我想到火热浪漫的海滩,撅着屁股晒太阳的美女,以及被暴力甩起又被摔碎的浪花。

魔幻的时间

关于时间的问题,首先让我们看一段神奇的代码。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sTime = "2020-03-08 00:00:00";
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));

Date time = sdf.parse(sTime);
System.out.println(time.getTime());
System.out.println(time);
Calendar cd = Calendar.getInstance();

cd.setTime(time);// 2小时以后是几点? cd.add(Calendar.HOUR, 2);

time = cd.getTime();
System.out.println("------------------------------");
System.out.println(time.getTime());
System.out.println(time);

我们从字符串生成了一个时间,就是上面邮件提到的时间。然后在此基础上加上了2个小时。结果运行的时候,神奇的事情发生了:打印结果显示,两个时间之间的差距是3个小时!

有图为证。

qE7NryU.png!web

真是见鬼。

这是时间魔幻性的一面。

夏令时会导致某一天多出一个小时,或者少出一个小时。

要了解夏令时,就首先需要了解时区的概念。在《时间的秩序》一书里,讲解到时区的诞生其实是多种方案权衡的结果。最终全球被分为24个时区,每个时区跨经度15°。

其中,北京时间,是中国采用国际时区 东八时区 的区时作为标准时间,也是我们现在用的时间,但它的位置是在山西蒲城。

但在清代,却是用北京中轴线上的 鼓楼 作为标准时间的。xjjdog在那里呆过一段时间,是一个非常美丽幽静的地方。

时间计时

扯了这么多没用的,我们来看一下常见的GMT和UTC。

一般对UTC和GMT的介绍都比较晦涩,我们平常在代码中遇到的时间有4种,下面以人话进行说明。

GMT

格林尼治标准时间,是指位于伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。

3UZ7NjV.jpg!web

为什么它就能成为本初子午线, 这不是地理原因,是历史原因 。要是我有话语权的话,我会将神奇的百慕大三角,如今的西经64°45′,定为0度。

UTC

UTC一般和GMT视为无差别的表示方法。但GMT是以地球自转来计时的,这个庞然大物并不是那么准确。

UTC是原子时计时,更加可靠。 每年格林尼治天文台会发调时信息,就是基于UTC的。

所以你现在看到的GMT,是旧世界的计时方法,最先进的计时,就是UTC。

协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。(这里面涉及到稳定的原子辐射,比地球的自转更加准确)。

UTC原子钟放在美国科罗拉州博尔德市, 最先进的铝离子光钟每237亿年偏差一秒! 谁能等到这一天别忘了把我从时光里挖出来。

Unix Time

Unix时间戳。是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。

意思就是,1970年前的时间戳,是负数。

为什么是1970?因为早期的机器都是32位的。用32位来表示时间的最大间隔是68年,而最早出现的UNIX操作系统考虑到计算机产生的年代和应用的时限综合取了1970年1月1日作为UNIX TIME的纪元时间。

夏令时DST

下面提到该死的夏令时。这是一个人为规定的时间。

一般在天亮的早的夏季, 人为将时间调快一小时 。这样可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。全世界有近110个国家每年要实行夏令时。

它又称“日光节约时制”和“夏令时间”,在这一制度实行期间所采用的统一时间称为“夏令时间”。

时间本来就是一个抽象的,看不见摸不着的东西。就连我们的钟表,也会在极限情况下失真。夏令时让时间更加复杂了一些。

影响

我们可以通过代码发现以下有悖常理的事情:

1)每一天并不总是有24小时,它还有可能是23,有可能是25。

2)Date日期处理类打印的并不总是如我们所愿。

public static void dayTime(TimeZone timeZone) {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("Time Zone is " + timeZone.getDisplayName() + " " + timeZone.getID());
Calendar start = Calendar.getInstance(timeZone);
//UTC 1970-01-01
start.setTime(new Date(0));
System.out.println("start=" + fmt.format(start.getTime()));
//current time
long end = Calendar.getInstance(timeZone).getTimeInMillis();
boolean find = false;
for (long i = start.getTimeInMillis(); i < end; i = start.getTimeInMillis()) {
start.add(Calendar.DATE, 1);
if ((start.getTimeInMillis() - i) % TimeUnit.DAYS.toMillis(1) != 0) {
find = true;
System.out.println("from " + fmt.format(new Date(i)) +
"to " + fmt.format(start.getTime()) +
" has " + (start.getTimeInMillis() - i) + "ms" +
"[" + (start.getTimeInMillis() - i) / (3600 * 1000L) + "hours]");
}
}
if (!find) {
System.out.println("Every day is ok.");
}
}

代码显示,在中国1986-1991年的这段时间里,一天并不总是有24个小时。

yyiYjen.png!web

这些肯定是属于比较个性化的数据了。那么,这些数据是从什么地方获取的呢?我们跟踪代码,可以发现 sun.util.calendar.ZoneInfo 类。而操作系统存放了每一个时区的具体配置文件,通过它们的配合,就能完成不同地域不同时间的展示。

因为时区问题造成的BUG是时有发生的,尤其是国际项目。由于时区的不同,有可能在录入部分人的出生日期时,会发现多了或者少了一天!比如中国,出生在1986-1991年的这些人,就可能碰到这种幽灵问题。

这一区间的小伙伴注意了,在某一刻,虽然活着,你可能并不存在!

各种时间表示这样转来转去的,总是让人头晕。好的办法就是,把所有的时区,调整成一致的。甚至是mysql,也提供了 serverTimezone 参数来进行统一协调。

&serverTimezone=Asia/Shanghai

JVM也提供了参数。

-Duser.timezone=GMT+8

几乎每个地方都充斥着这该死的timezone。是我们太弱小了,连个地球都没统一起来。

实际上,夏令时在中国,从1986-1992只实行了6年,之后就取消了。真是谢天谢地,每一天可以踏踏实实的睡觉,不用担心这些灵异事件了。

加上科技的发达,城里6点就亮起了霓虹灯。哪里还有什么白天黑夜。是时候全部取消夏令时了,可惜我说了不算(狗头保命)。

End

下次要是有人问你,一天有24个小时么?不要像刚认识数字的小学生一样,行高彩烈的喊是。由于夏令时的加入,可能在你眨一下眼睛之间,“一个小时”就过去了。

时间是个相对的产物,不同的人有不同的看法。比如,空姐的手表,总是比你的走的慢一些—这就是她们年轻一点的原因。

随着我们对世界的了解,很多以前坚定不移的认为对的事情,已经慢慢的开始腐烂变质。我们只是习惯,但事实从未变过。

就如同你认为现在打字的我是个程序员,但实际上我是一只狗。

意识形态的东西,谁能说得清呢。

近期热门文章

996的乐趣,你是无法想象的

魔幻现实主义,关爱神经衰弱

一切荒诞的傲慢,皆来源于认知

不要被标题给骗了,画面感十足的消遣文章

《必看!java后端,亮剑诛仙》

后端技术索引,中肯火爆。全网转载上百次。

《学完这100多技术,能当架构师么?(非广告)》

精准点评100多框架,帮你选型

作者简介: 小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流

EnUneen.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK