我有一个boost::posix_time::ptime
对象(Boost v1.60),它在系统的时区中有日期和时间信息。我需要将其转换为UTC的unix时间戳。
time_t convertLocalPtimeToTimestamp(const boost::posix_time::ptime& pt)
{
using namespace boost::local_time;
static const time_t t_null = 0;
static struct tm* tm_local = localtime(&t_null);
static time_zone_ptr zone(new posix_time_zone(tm_local->tm_zone));
LOG(debug) << "Zone " << zone->to_posix_string();
local_date_time az(pt.date(), pt.time_of_day(), zone, local_date_time::EXCEPTION_ON_ERROR);
LOG(debug) << "local_date_time: " << az;
LOG(debug) << "local_time: " << az.local_time();
LOG(debug) << "utc_time: " << az.utc_time();
struct tm t = to_tm(az);
time_t ts = mktime(&t);
return ts;
}
我的案例(欧洲/马德里)的结果是:
Zone CET+00
local_date_time: 2016-Oct-05 17:36:27.701162 CET
local_time: 2016-Oct-05 17:36:27.701162
utc_time: 2016-Oct-05 17:36:27.701162
1475685387
此结果中存在各种错误:
任何帮助都将不胜感激。
答案 0 :(得分:3)
Fwiw,来自free, open source library:
#include "chrono_io.h"
#include "tz.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std::chrono;
auto az = make_zoned("Europe/Madrid",
local_days{2016_y/oct/5} + 17h + 36min + 27s + 701162us);
std::cout << "Zone " << az.get_time_zone()->name() << '\n';
std::cout << "local_date_time: " << az << '\n';
std::cout << "local_time: " << az.get_local_time() << '\n';
std::cout << "utc_time: " << az.get_sys_time() << '\n';
std::cout << floor<seconds>(az.get_sys_time()).time_since_epoch() << '\n';
}
输出是:
Zone Europe/Madrid
local_date_time: 2016-10-05 17:36:27.701162 CEST
local_time: 2016-10-05 17:36:27.701162
utc_time: 2016-10-05 15:36:27.701162
1475681787s
还可以使用zoned_time
构建current_zone()
,如下所示:
auto az = make_zoned(current_zone(),
local_days{2016_y/oct/5} + 17h + 36min + 27s + 701162us);
或者:
auto az = make_zoned(current_zone(), system_clock::now());
答案 1 :(得分:3)
这是我要解决的问题的Boost实现。
我不想使用其他第三方库,我在Windows中遇到了jgaida的问题(tm_zone和tm_gmtoff不是tm的成员)。
我通过多次更改Windows 10 PC中的时区来测试此代码。
边缘情况&#34;(UTC-12:00)国际日期线西&#34;和#34;(UTC + 14:00)Kiritimati岛)&#34;也进行了测试,结果很成功。
n = 0..7
答案 2 :(得分:0)
与此同时,我发现了一种在Linux中检测UTC偏移的简单方法。似乎localtime
期望非空时间戳计算当前时区和偏移量。这种方式有效:
time_t convertLocalPtimeToTimestamp(const boost::posix_time::ptime& pt)
{
time_t tt = to_time_t(pt);
struct tm* local = localtime(&tt);
LOG(debug) << "Timezone: " << local->tm_zone << " Offset: " << local->tm_gmtoff;
return (tt - local->tm_gmtoff);
}
我知道,有一个缺陷,因为我从当地时间获得当前时区,因此在夏令时变化周围的小时内会有一个偏移。但就我的目的而言,这不是问题。