我正在尝试将我认为是UTC字符串的时间信息转换为std::mktime
在C++中使用的时间戳.我的问题是,
/
没有转换为UTC的功能; mktime只会将时间戳作为本地时间返回.
所以我需要弄清楚时区偏移量并将其考虑在内,但我找不到与平台无关的方法,不涉及将整个代码移植到boost::date_time
.有一些我忽略的简单解决方案吗?
timestamp = mktime(&tm) - _timezone;
或平台独立方式:
timestamp = mktime(&tm) - timezone;
如果你查看mktime()的来源:
http://www.raspberryginger.com/jbailey/minix/html/mktime_8c-source.html
在00117行中转换为当地时间的时间:
seconds += _timezone;
mktime()使用tzname来检测时区.tzset()从TZ环境变量初始化tzname变量.如果TZ变量出现在环境中但其值为空或其值无法正确解释,则使用UTC.
根据timegm联机帮助页的便携式(非线程安全)版本
#include#include time_t my_timegm(struct tm *tm) { time_t ret; char *tz; tz = getenv("TZ"); setenv("TZ", "", 1); tzset(); ret = mktime(tm); if (tz) setenv("TZ", tz, 1); else unsetenv("TZ"); tzset(); return ret; }
Eric S Raymond在他的文章" Time,Clock,and Calendar Programming In C"中发表了一个线程安全版本
time_t my_timegm(register struct tm * t) /* struct tm to seconds since Unix epoch */ { register long year; register time_t result; #define MONTHSPERYEAR 12 /* months per calendar year */ static const int cumdays[MONTHSPERYEAR] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; /*@ +matchanyintegral @*/ year = 1900 + t->tm_year + t->tm_mon / MONTHSPERYEAR; result = (year - 1970) * 365 + cumdays[t->tm_mon % MONTHSPERYEAR]; result += (year - 1968) / 4; result -= (year - 1900) / 100; result += (year - 1600) / 400; if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0) && (t->tm_mon % MONTHSPERYEAR) < 2) result--; result += t->tm_mday - 1; result *= 24; result += t->tm_hour; result *= 60; result += t->tm_min; result *= 60; result += t->tm_sec; if (t->tm_isdst == 1) result -= 3600; /*@ -matchanyintegral @*/ return (result); }