我已经在其他编程语言或操作系统上看到了与此问题相关的一些问题/答案,但我没有找到适合我的特定场景的通用解决方案。我想在 Linux shell 脚本或纯 C 中获取给定时区的 GMT 偏移量(正常标识符,如 EDT、CET 或欧洲/柏林)。
一个简单的解决方案是:
$ TZ=":Europe/Berlin" date +%z
但这将打印当前 GMT 偏移量(如果当前正在使用,则包括 DST)。
这里有一个更好的例子来说明我的意思:
$ TZ=":Europe/Berlin" date +%z --date="1 Jan 2014"
+0100
$ TZ=":Europe/Berlin" date +%z --date="1 May 2014"
+0200
我需要一个选项来始终获取任何国家/城市的非 DST 值(此处:+0100)。
其他可以解决我的问题并与此问题相关的问题:
如何在事先不知道偏移量的情况下找到给定城市(欧洲/柏林)的正确非 DST 时区(Etc/GMT-1)?
您通常如何知道 DST 在给定时间戳处于事件状态?
$ TZ=":Europe/Berlin" date --date="2014-01-01"
Wed Jan 1 00:00:00 CET 2014
$ TZ=":Europe/Berlin" date --date="2014-05-01"
Thu May 1 00:00:00 CEST 2014
标识符 CEST(中欧夏令时)和 CET(中欧时间)在世界其他地方可能并不为人所知,因此选择简单地获取类似 DST=1 或 DST=0 的选项会更好,如果有人需要它。通过 zdump,您可以获得所有更改 DST 的时间戳的 isdst=0 或 isdst=1,但它在 IMO 上并不那么容易使用。
最佳答案
这将以秒为单位返回给定时区当年与 GMT 的非 DST 偏移量:
zdump -v "Europe/Berlin" | \
sed ":a;N;\$!ba;s/^.*$(echo -n $(date +%Y)) [^ ]* isdst=0 \
gmtoff=\([^\n]*\)\n.*$/\1/"
3600
这里发生的事情是 sed 匹配 zdump 为该时区返回的当年第一条非 dst 行,然后用第一条匹配行的末尾替换整个 zdump 输出,即 GMT以秒为单位的偏移量。
如果您需要将其格式化为+HHMM 或-HHMM:
offsetArray=($(zdump -v "America/New_York" | \
sed ":a;N;\$!ba;s/^.*$(echo -n $(date +%Y)) [^ ]* isdst=0 \
gmtoff=\(-*\)\([^\n]*\)\n.*$/\1+ \2/"))
echo "${offsetArray[0]:0:1}$(date -ud @${offsetArray[1]} +%H%M)"
-0500
这将创建一个包含两个元素的数组,符号和偏移量的绝对值(以秒为单位)。它输出前者,并通过将日期作为自纪元(1970 年 1 月 1 日 00:00:00 UTC/GMT)以来的时间传递来格式化后者。因为 Bash 数组赋值忽略前导空格,所以数组的第一个元素实际上是“+”或“-+”,显示的是第一个字符(即+或-)。
顺便说一句,我认为 zdump 列出的每一年都应该与 GMT 具有相同的非 DST 偏移量,而我最初的答案只是 sed grab 它找到的第一年,但我编辑了答案以检查当前年以适应理论边缘情况,即自 1901 年以来时区发生变化的情况。
(您可以删除结尾的反斜杠,以便将所有指令都放在一行中,或者在第二个示例中是两行。)
关于linux - 没有夏令时 (DST) 的给定时区的 GMT/UTC 偏移量(小时/分钟),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23218788/