在 bash 中检测夏令时

问题描述 投票:0回答:4

我想检测我是在冬天还是夏天。我目前的做法是:

if date +%Z | grep -e CET -e EST; then
  # I'm in winter time
else
  # I'm in summer time
fi

这有明显的缺点,因为你必须知道所有时区名称。

bash date dst
4个回答
12
投票

我现在不知道这是否完全回答了您的问题,但它为您提供了一些工具来帮助您更好地理解和测试正在发生的事情。

您可以使用

date
和环境变量
TZ
来帮助您。

例如,我住在瑞典,所以我的时区位置是欧洲/斯德哥尔摩。因此,冬季

date +%Z
报告 CET,夏季报告 CEST。好处是您可以为特定命令的环境指定时区,然后您可以指定
date
命令应显示的日期。因此,通过总结这一点,您可以执行以下任一操作:

TZ=Europe/Stockholm date +%Z # CET or CEST depending of when its run
TZ=Europe/Stockholm date --date=20170101 +%Z # CET
TZ=Europe/Stockholm date --date=20170601 +%Z # CEST
TZ=CET date --date=20170101 +%Z # CET
TZ=CET date --date=20170601 +%Z # CEST, note that its auto adjusted to CEST

如果您想要与 UTC 的时差,您可以使用小写-z:

TZ=Europe/Stockholm date +%z # +0100 or +0200 depending of when its run
TZ=Europe/Stockholm date --date=20170101 +%z # +0100
TZ=Europe/Stockholm date --date=20170601 +%z # +0200
TZ=CET date --date=20170101 +%z # +0100
TZ=CET date --date=20170601 +%z # +0200

注意:您不能使用

TZ=CEST
TZ=ULFR
,因为这不是有效的 TZ:

TZ=CEST date --date=20170101 +%z # +0000
TZ=ULFR date --date=20170101 +%z # +0000

crontab 示例:

我们在 UTC 上运行服务器,但 crontab 运行的一些作业需要在指定的挂钟 (CET/CEST) 时间运行。因此,由于我们希望作业在冬天晚一小时运行(在夏天时钟提前一小时,使得夏天比冬天早一小时到达指定的 UTC 时间),我们这样做

sleep 
在冬季实际工作执行之前。

我们希望作业

/whatever/bin/foobar
每天在
04:15
挂钟时间运行。但由于 cron 在 UTC 上运行,因此需要将作业设置为 CET 提前一小时,CEST 提前两小时。这与总是提前两个小时运行命令但在冬天睡一个小时是一样的。前 crontab 行:

15 2 * * * [ `TZ=CET date +\%Z` = CET ] && sleep 3600; /whatever/bin/foobar

如果您对这个问题有更好的解决方案,请随时给我建议!


11
投票

Perl 来救援:

if perl -e 'exit ((localtime)[8])' ; then
    echo winter
else
    echo summer
fi

那是因为 localtime 返回以下列表:

#     0    1    2     3     4    5     6     7     8
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                                            localtime(time);

其中“isdst”代表是夏令时


10
投票

在北半球实行夏令时的地区,当偏移量大于一月份的偏移量时,它就会处于活动状态。 在南半球时区,当偏移量大于 7 月时,夏令时就会生效。

您可以发现一月和七月以及现在的抵消量:

OFF_1=$(date -d '1 Jan' +%z)
OFF_7=$(date -d '1 Jul' +%z)
OFF_NOW=$(date +%z)

如果您的区域没有夏令时,则所有三个区域都将相同(今年)。 不管怎样,我们可以做两个比较,一是北半球,一是南半球;如果当前偏移量大于其中之一,则当前区域处于夏令时:

if  test $OFF_NOW -gt $OFF_1  ||  test $OFF_NOW -gt $OFF_7
then
  # I'm in summer time with daylight savings
else
  # I'm in winter time or a region without daylight savings
fi

此处的假设是,所有实行夏令时的地区都会在 7 月到 1 月之间进行过渡。 据我所知,所有地区都是如此。 唯一可能失败的情况是冬季偏移发生变化的一年(例如英国的 1940 年,随后的冬季是 GMT+1)。


2
投票

信息:

zdump -v Europe/Paris | grep 2020

给出了这个:

Europe/Paris  Sun Mar 29 00:59:59 2020 UT = Sun Mar 29 01:59:59 2020 CET isdst=0 gmtoff=3600
Europe/Paris  Sun Mar 29 01:00:00 2020 UT = Sun Mar 29 03:00:00 2020 CEST isdst=1 gmtoff=7200
Europe/Paris  Sun Oct 25 00:59:59 2020 UT = Sun Oct 25 02:59:59 2020 CEST isdst=1 gmtoff=7200
Europe/Paris  Sun Oct 25 01:00:00 2020 UT = Sun Oct 25 02:00:00 2020 CET isdst=0 gmtoff=3600
© www.soinside.com 2019 - 2024. All rights reserved.