在 Solaris 上使用时区偏移时,我遇到了 date 命令的奇怪行为。
>echo $TZ
MET
>date
Wed Mar 31 11:41:45 MEST 2021
>TZ=MET+24 date
Tue Mar 30 09:42:06 MET 2021
>TZ=MEST+24 date
Tue Mar 30 09:42:52 MEST 2021
当 TZ 设置为 MET 时,为什么日期输出显示 MEST,以及 TZ+24 在两个时区中如何显示 26 小时偏移而不是 24 小时。
答案1
因此,您希望了解为什么会发生这种情况(简化):
$ TZ=MET date; TZ=MET+0 date
Tue 01 Jun 2021 06:00:00 AM MEST
Tue 01 Jun 2021 04:00:00 AM MET
MET
即:和之间相差两个小时MET+0
。
调试此问题的最简单方法是添加'+%z'
格式。这将打印日期用于打印结果的偏移量,并可以帮助调试问题出在哪里。
$ TZ=MET date "+%c %z"; TZ=MET+0 date "+%c %z"
Wed 31 Mar 2021 06:11:16 PM MEST +0200
Wed 31 Mar 2021 04:11:16 PM MET +0000
-2
这表明日期正在打印偏移量和偏移量的结果+0
。
那么问题是:为什么?
也许是因为 TZ 的第一个格式是std offset
(类似于 TAG-03POSIX 参考)其中标签定义了标准区域的范围,并给出了此类标签的可选偏移量。如果丢失,则假定偏移量为+0
。
因此,我们将 MET 设置name
为 MET,并将偏移量设置为 +0。
证明:
$ TZ=MET date "+%c %z"; TZ=METX+7:30 date "+%c %z"
Wed 31 Mar 2021 06:19:00 PM MEST +0200
Wed 31 Mar 2021 08:49:00 AM METX -0730
这标签很简单:它是将打印的时区名称。
用于此类标签的偏移量是给定的:(-7:30
不问任何问题)。
您应该清楚,METX
任何地方都没有这样的标签,而且该标签上没有这样的 7:30 偏移量。
这解释了为什么 aMET+24
打印了带有标签的区域时间MET
和昨天的偏移量+0
(相当于+24
,+12
如果您愿意,请尝试)。
正确的 TZ
我们可以测试一个 TZ说标准时间为 7 小时,夏令时间为 9 小时:MET-7MEST-9。为了进行测试,我们需要 faketime(需要针对 Solaris 进行编译),它会打印:
$ # In January (no DST):
$ faketime "1/1/21 12:00" bash -c 'date -u; TZ=MET date "+%c %z"'; \
faketime "1/1/21 12:00" bash -c 'TZ=MET-7MEST-9 date "+%c %z"'
Fri 01 Jan 2021 04:00:00 PM UTC
Fri 01 Jan 2021 05:00:00 PM MET +0100
Fri 01 Jan 2021 11:00:00 PM MET +0700
$ # In June (DST in effect)
$ faketime "6/1/21 12:00" bash -c 'date -u; TZ=MET date "+%c %z"'; \
faketime "6/1/21 12:00" bash -c 'TZ=MET-7MEST-9 date "+%c %z"'
Tue 01 Jun 2021 04:00:00 PM UTC
Tue 01 Jun 2021 06:00:00 PM MEST +0200
Wed 02 Jun 2021 01:00:00 AM MEST +0900
这只是为了证实我们的分析。 TZ 值可以减少为MET-7MEST因为 DST 的默认效果是将时间增加 1 小时。而且,由于 MET 的真实 UTC 偏移量是 +1,我们可以确定 TZ 应该是:MET-1MEST。如果缺少 dst 标记 ( MET-1
),则不应用 dst 偏移量。
为了您设定时间的目标昨天(+24 小时),您应该使用:
TZ='MET+23MEST'
问题?
答案2
单独的MET显然是指中欧时间(= UTC+1小时),在3月的最后一个周日(今年3月28日)过渡到夏令时版本(UTC+2小时),DST版本被称为中欧时间夏令时。因此,“MET”实际上被解释为“MET-1MEST”的简写。 2 小时的总 UTC 差异来自 1 小时基于时区的 UTC 偏移量和 1 小时 DST 偏移量。
由此,我还可以看到您输入这些命令时的基本 UTC 时间约为 09:42 UTC。
但是,当您指定“MET+24”时,那就是“一些奇怪的时区,它使用标识符 MET 并转换为 UTC,以便(本地时间)+ 24 h = UTC”。为了将 UTC 转换为本地时间,该公式反向应用,因此“MET+24 时区的本地时间”是 UTC - 24 小时,或者恰好是过去一天的 UTC 时间。
由于“MET+24”没有 DST 规则,因此不会应用 DST 校正。