Erlang Thursday – calendar:local_time_to_universal_time_dst/1

(译者注:本文里的例子结果在中国时区是不同的)

为了纪念本周末的时间变化,今天的 Erlang Thursday 要讲的函数是 calendar:local_time_to_universal_time_dst/1.

为了更好地理解 calendar:local_time_to_universal_time_dst/1 是做什么的,我们将用它和 calendar:local_time_to_universal_time/1 进行比较。

即将到来的星期日我们将在临晨两点把时钟拨快一个小时,那么让我们来看看在临晨一点五十九分的时候UTC时间是多少?

1
2
calendar:local_time_to_universal_time({{2015,3,8},{1,59,59}}).
% {{2015,3,8},{7,59,59}}

现在让我们看看当日临晨两点的时候 calendar:local_time_to_universal_time/1 返回的UTC时间是多少,实际上当日临晨两点我们根本没有到达过,因为我们直接将时间向前拨快了到临晨三点。

1
2
calendar:local_time_to_universal_time({{2015,3,8},{2,00,00}}).
% {{2015,3,8},{8,0,0}}

但是当我们深入函数库里,我们看到也有另外一个函数 calendar:local_time_to_universal_time_dst/1. calendar:local_time_to_universal_time_dst/1 返回值是一个由时间元组组成的列表,让我们开始看看为什么这很重要。

此时,让我调用 calendar:local_time_to_universal_time_dst/1 并传入当日临晨两点作为参数,然后我们看到的结果是什么呢。

1
2
calendar:local_time_to_universal_time_dst({{2015,3,8},{2,00,00}}).
% []

一个空列表!

如果你花一点时间来想一想,这是有道理的,因为临晨两点根本就没发生过,所以就没有UTC时间和它对应上。

那么当我们跳到临晨三点我们看到什么呢?我们将得到早上八点UTC时间,这仅仅是在临晨一点五十九分五十九秒的一秒之后的UTC时间。

1
2
3
calendar:local_time_to_universal_time_dst({{2015,3,8},{3,00,00}}).
% [{{2015,3,8},{8,0,0}}]
`

为了涵盖本周末的情况,让我们来看看在今年晚些时候也就是11月1日将时钟拨慢一小时会发生什么。

从一个基准时间开始,让我们看看零点五十九分五十九秒(译者注:原文是12:59:59AM,应该是作者手误)是多少UTC时间,我们知道这个时间我们将仅遇到一次。

1
2
3
4
5
calendar:local_time_to_universal_time({{2015,11,1},{0,59,59}}).
% {{2015,11,1},{5,59,59}}
calendar:local_time_to_universal_time_dst({{2015,11,1},{0,59,59}}).
% [{{2015,11,1},{5,59,59}}]
`

而且即使时间的变化发生在临晨两点,我们仍然只是遇到一次,因为我们第一次直接移动到临晨一点。

1
2
3
calendar:local_time_to_universal_time_dst({{2015,11,1},{2,0,0}}).
% [{{2015,11,1},{8,0,0}}]
`

所以零点五十九分五十九秒,我们得到UTC时间五点五十九分五十九秒,而两点,我们得到UTC时间是八点。现在到了棘手的部分,凌晨一点。

临晨一点是一个奇怪的场景,当日晚上我们将度过两个临晨一点。那么让我们看看Erlang在这种情况下做了什么。

首先,我们看看在临晨一点的时候我们调用 calendar:local_time_to_universal_time 得到的UTC时间是多少。

1
2
calendar:local_time_to_universal_time({{2015,11,1},{1,00,00}}).
% {{2015,11,1},{6,0,0}}

我们得到UTC时间是六点。我们从UTC时间五点五十九分五十九秒移动到UTC时间六点;这是合理的,直到我们开始怀疑我们第二次遇到临晨一点。

现在,让我们看看在临晨一点的时候我们调用 calendar:local_time_to_universal_time_dst/1 会得到什么UTC时间。

1
2
3
calendar:local_time_to_universal_time_dst({{2015,11,1},{1,0,0}}).
% [{{2015,11,1},{6,0,0}},{{2015,11,1},{7,0,0}}]
`

我们得到由两个UTC时间组成的列表,一个是我们第一次遇到临晨一点时的UTC时间六点,另一个是我们第二次遇到临晨一点的UTC时间七点。这个返回两个UTC时间的情况也在临晨一点内的每秒钟出现。(译者注:原文是every time,译者认为应该是every second)

1
2
calendar:local_time_to_universal_time_dst({{2015,11,1},{1,59,59}}).
% [{{2015,11,1},{6,59,59}},{{2015,11,1},{7,59,59}}]

通过返回没有元素、一个元素或者两个元素的列表,Erlang提供给你最精确的信息为你所用,同时让你做出希望如何处理时间的明智的决定,而不是为你做出一些决定即使它们不符合你的系统需要。

原文链接: https://www.proctor-it.com/erlang-thursday-calendar-local_time_to_universal_time_dst-1/