当前位置:  开发笔记 > 编程语言 > 正文

如何找到当前系统时区?

如何解决《如何找到当前系统时区?》经验,为你挑选了3个好方法。

在Linux上,我需要找到当前配置的时区作为Olson位置.我希望我的(C或C++)代码可以移植到尽可能多的Linux系统.

例如.我住在伦敦,所以我现在的奥尔森位置是"欧洲/伦敦".我对时区ID 感兴趣,比如"BST","EST"等等.

Debian和Ubuntu有一个/etc/timezone包含这些信息的文件,但我认为我不能依赖那个文件,我可以吗?Gnome有一个函数oobs_time_config_get_timezone()也返回正确的字符串,但我希望我的代码可以在没有Gnome的系统上运行.

那么,在Linux上获得当前配置的时区作为Olson位置的最佳通用方法是什么?



1> psmears..:

这是很难得到一个可靠的答案.依靠这样的事情/etc/timezone可能是最好的选择.

(如其他答案中所建议的,变量tznametm_zone成员struct tm通常包含缩写,例如GMT/ BSTetc,而不是问题中请求的Olson时间字符串).

在基于Debian的系统(包括Ubuntu)上,/etc/timezone是一个包含正确答案的文件.

在一些基于Redhat的系统(包括至少某些版本的CentOS,RHEL,Fedora)上,您可以使用readlink()on获取所需的信息/etc/localtime,这是(例如)的符号链接/usr/share/zoneinfo/Europe/London.

OpenBSD似乎使用与RedHat相同的方案.

但是,上述方法存在一些问题.该/usr/share/zoneinfo目录还包含诸如GMT和之类的文件GB,因此用户可以将符号链接配置为指向那里.

此外,没有什么可以阻止用户在那里复制正确的时区文件而不是创建符号链接.

绕过它的一种可能性(似乎适用于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为符号链接; 如果失败,搜索匹配的时区定义文件; 如果失败了 - 放弃回家;-)

(而且我不知道上述任何一个是否适用于AIX ......)



2> Evan Teran..:

这没有标准的 c或c ++功能.但是,GNU libc有一个扩展.它struct tm有两个额外的成员:

long tm_gmtoff;           /* Seconds east of UTC */
const char *tm_zone;      /* Timezone abbreviation */

这意味着如果您使用填充a struct tm(例如localtimeor gmtime)的函数之一,则可以使用这些额外字段.这当然只有在您使用GNU libc(以及它的最新版本)时才会这样.

此外,许多系统都有一个int gettimeofday(struct timeval *tv, struct timezone *tz);功能(POSIX),它将填写一个struct timezone.这包含以下字段:

struct timezone {
    int tz_minuteswest;     /* minutes west of Greenwich */
    int tz_dsttime;         /* type of DST correction */
};

不完全是你要求的,但关闭......


回复:gettimeofday的,最近的文档包含下面的注释:"使用该时区的结构已经过时;在TZ参数通常应指定为NULL的tz_dsttime场从未在Linux下使用,它一直没有,也不会得到支持.通过libc或glibc.内核源代码中每个出现的这个字段(声明除外)都是一个错误."

3> Howard Hinna..:

我一直在开发一个免费的开源C++ 11/14库,它只需一行代码即可解决这个问题:

std::cout << date::current_zone()->name() << '\n';

它适用于所有最新版本的Linux,macOS和Windows.对我来说,这个程序输出:

America/New_York

如果您下载此库,但它不起作用,欢迎使用错误报告.

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有