在 Linux 上,我需要找到当前配置的时区作为 Olson 位置。我希望我的(C 或 C++)代码可以移植到尽可能多的 Linux 系统。
例如。我住在伦敦,所以我目前的奥尔森位置是“欧洲/伦敦”。我不对“BST”、“EST”等时区 ID 感兴趣。
Debian 和 Ubuntu 有一个文件 /etc/timezone
包含此信息,但我认为我不能依赖该文件始终存在,可以吗? Gnome 有一个函数 oobs_time_config_get_timezone()
也返回正确的字符串,但我希望我的代码在没有 Gnome 的系统上工作。
那么,在 Linux 上将当前配置的时区作为 Olson 位置的最佳通用方法是什么?
最佳答案
它是 hard to get a reliable answer .依赖像 /etc/timezone
这样的东西可能是最好的选择。
(如其他答案中所建议的,变量 tzname
和 struct tm
的 tm_zone
成员通常包含缩写,例如 GMT
/BST
等,而不是问题中要求的 Olson 时间字符串。
/etc/timezone
是一个包含正确答案的文件。/etc/localtime
上的 readlink() 获取所需的信息,这是一个符号链接(symbolic link)到(例如)/usr/share/zoneinfo/Europe/London
。但是,上述方法存在一些问题。 /usr/share/zoneinfo
目录还包含诸如 GMT
和 GB
等文件,因此用户可以配置符号链接(symbolic link)指向那里.
此外,没有什么可以阻止用户在那里复制正确的时区文件而不是创建符号链接(symbolic link)。
解决这个问题的一种可能性(这似乎适用于 Debian、RedHat 和 OpenBSD)是将/etc/localtime 文件的内容与/usr/share/zoneinfo 下的文件进行比较,并查看哪些匹配:
eta:~% md5sum /etc/localtime
410c65079e6d14f4eedf50c19bd073f8 /etc/localtime
eta:~% find /usr/share/zoneinfo -type f | xargs md5sum | grep 410c65079e6d14f4eedf50c19bd073f8
410c65079e6d14f4eedf50c19bd073f8 /usr/share/zoneinfo/Europe/London
410c65079e6d14f4eedf50c19bd073f8 /usr/share/zoneinfo/Europe/Belfast
410c65079e6d14f4eedf50c19bd073f8 /usr/share/zoneinfo/Europe/Guernsey
410c65079e6d14f4eedf50c19bd073f8 /usr/share/zoneinfo/Europe/Jersey
410c65079e6d14f4eedf50c19bd073f8 /usr/share/zoneinfo/Europe/Isle_of_Man
...
...
当然,缺点是它会告诉你所有与当前时区相同的时区。 (这意味着完全意义上的相同——不仅仅是“当前同时”,而且“就系统所知,总是在同一天改变他们的时钟”。)
您最好的选择可能是结合上述方法:使用 /etc/timezone
(如果存在);否则尝试将 /etc/localtime
解析为符号链接(symbolic link);如果失败,搜索匹配的时区定义文件;如果失败 - 放弃并回家;-)
(而且我不知道以上是否适用于 AIX...)
https://stackoverflow.com/questions/3118582/