在我见过的大多数例子中:
time_zone_ptr zone( new posix_time_zone("MST-07") );
但我只想获得运行代码的机器的当前时区。我不想硬编码时区名称。
答案 0 :(得分:10)
普通posix:call tzset, use tzname。
#include <ctime>
tzset();
time_zone_ptr zone(new posix_time_zone(tzname[localtime(0)->tm_isdst]));
添加glibc/bsd的Posix:
time_zone_ptr zone(new posix_time_zone(localtime(0)->tm_zone));
上面缩写为Posix timezones,根据与UTC的偏移量定义,并且随着时间的推移不稳定(有一个更长的形式可以包括DST转换,但不包括政治和历史转换)。
ICU是可移植的,并且具有将系统时区检索为Olson时区的逻辑(sumwale的代码段):
// Link with LDLIBS=`pkg-config icu-i18n --libs`
#include <unicode/timezone.h>
#include <iostream>
using namespace U_ICU_NAMESPACE;
int main() {
TimeZone* tz = TimeZone::createDefault();
UnicodeString us;
std::string s;
tz->getID(us);
us.toUTF8String(s);
std::cout << "Current timezone ID: " << s << '\n';
delete tz;
}
在Linux上,ICU实现与tzset兼容并查看TZ
和/etc/localtime
,它们在最近的Linux系统上被称为包含Olson标识符的符号链接(here's the history )。有关实施细节,请参阅uprv_tzname
。
Boost不知道如何使用Olson标识符。您可以使用非DST和DST偏移构建posix_time_zone
,但此时,最好继续使用ICU实现。请参阅this Boost FAQ。
答案 1 :(得分:4)
当天很晚,但我正在寻找类似的东西,所以这可以帮助别人。使用strftime的以下(非增强)方式似乎适用于大多数平台:
time_t ts = 0;
struct tm t;
char buf[16];
::localtime_r(&ts, &t);
::strftime(buf, sizeof(buf), "%z", &t);
std::cout << "Current timezone: " << buf << std::endl;
::strftime(buf, sizeof(buf), "%Z", &t);
std::cout << "Current timezone: " << buf << std::endl;
或者可以将std :: time_put用于纯C ++版本。
答案 2 :(得分:1)
好吧,也许你可以使用GeoIP库来做到这一点。我知道这有点过分,但由于世界上大多数计算机都连接到互联网,你可能会侥幸逃脱。根据我正在开发的那个人,它的准确度超过了99%。
注意:这是一个愚蠢的想法。我只是在寻找答案。
答案 3 :(得分:1)
为了正确回答这个问题,重要的是要了解Boost中的时区支持受到严重限制。
它主要关注POSIX时区,它有几个局限性。 the timezone tag wiki的POSIX部分讨论了这些限制,因此我在此不再赘述。
它具有与IANA / Olson时区ID配合使用的功能,但它会人为地将这些功能映射到POSIX值 - 这会将时区展平为历史记录中的单个点。这些映射存储在Boost源代码中的a csv file中。
自2011年4月以来,csv文件尚未更新,此后对时区进行了许多更改。所以,它所做的映射有些不准确。
一般情况下,我不建议使用Boost来处理时区。相反,请考虑ICU TimeZone Classes,它是ICU项目的一部分。您会发现这些都是完全可移植的,并且它们具有完整且正确的时区支持。
值得一提的是ICU用于许多流行的应用程序。例如,Google Chrome网络浏览器可以获得ICU的时区支持。
在ICU中,当前本地系统时区可用作默认时区。您可以在ICU文档中的"Factory Methods and the Default Timezone"部分阅读更多内容。
答案 4 :(得分:0)
你总是可以尝试从增强和检查差异中获得通用时间和当地时间,但它可能充满警告。