在我看过的大部分示例中:
time_zone_ptr zone( new posix_time_zone("MST-07") );
但是我只想获取运行代码的机器的当前时区。我不想硬编码时区名称。
在我看过的大部分示例中:
time_zone_ptr zone( new posix_time_zone("MST-07") );
但是我只想获取运行代码的机器的当前时区。我不想硬编码时区名称。
普通的posix: 调用tzset函数,使用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));
// 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标识符(这里有历史信息)。有关实现详细信息,请参见uprv_tzname
。
Boost不知道如何使用Olson标识符。您可以使用非DST和DST偏移量构建posix_time_zone
,但此时最好继续使用ICU实现。请参见这个Boost FAQ。
虽然有些晚,但我正在寻找类似的东西,希望这可以帮助其他人。以下是一种(非boost)使用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++版本。
嗯,也许你可以使用GeoIP库来实现。我知道这有点过度杀伤力,但由于世界上大多数计算机都连接到互联网,你可能可以摆脱它。根据我正在为其开发的人说,它的准确率超过99%。
注意:这是一个愚蠢的想法。我只是在寻找答案。
time_zone_ptr
正确设置为机器当前时区的方法 - 这就是问题所问的。你可以想象我不想添加另一个依赖项,而且这个问题是关于boost的,但如果唯一的可能性是使用ICU,那就这样吧。不幸的是,你回答中唯一与此相关的部分只有链接,没有实质内容。 - BartoszKP
_get_tzname()
实现会返回一个名称,例如“Pacific Standard Time”;Boost库的posix_time_zone
需要类似于“PST”的内容。另外,顺便提一下,tzname
(在POSIX中,标准称其为_tzname
)是一个二维字符数组。[如果您定义了#define _POSIX_
,则MSVC还提供了TZNAME_MAX
,但设置为10,显然是早期实现中的疏忽。] - Mike C_tzset()
仅适用于UTC偏移量,但无法正确解释TZ变量中的DST更改定义(某些特定的美国规则是硬编码的)。 - BartoszKP