我需要能够将Epoch时间转换为Excel时间。 为什么选择Excel,因为使用数字excel时间比在显示格式上进行任何解析更快。
2018-06-08 12:46:58 CDT
与UTC 1528480019的当前时间应为 0.5326157 。
但转换为New_York时间或2018-06-08 13:46:58 EDT
将给出 0.574282367 。
我只需要将时间字段转换为Excel样式。
这是我不完整的代码:
double GetTime(Datetime currtime, std::string tz = "TZ=America/New_York")
{
std::time_t t = currtime;
//tzset(tz);
std::tm tm = *std::localtime(&t);
return ((tm.tm_hour * 3600 + (tm.tm_min) * 60.0 + tm.tm_sec) / 86400.0);
}
代码有效,但仅适用于当地时间“美国/芝加哥”。 我无法将时区设置为我可能需要的时区。 此外,tm似乎仅限于秒,但我也需要处理毫秒和微秒。
此外,我需要快速,并且当前实现将时间解析为单独的字段,然后我将其组合到我需要的内容中,这似乎做了很多额外的工作。
答案 0 :(得分:0)
使用Howard Hinnant's free, open-source date/time/timezone library可以轻松解决此问题,这非常有效。该库也在namespace std::chrono
下的当前C ++ 20工作草案中。因此,在将来,将代码移植到仅使用std :: lib应该像更改一些名称空间一样简单。
double
GetTime(std::chrono::system_clock::time_point currtime,
date::time_zone const* tz = date::current_zone())
{
using namespace date;
using namespace std::chrono;
zoned_time<system_clock::duration> zt{tz, currtime};
auto lt = zt.get_local_time();
auto ld = floor<days>(lt);
using ExcelTime = duration<double, days::period>;
ExcelTime tod = lt - ld;
return tod.count();
}
取代Datetime
而不是std::chrono::system_clock::time_point
,而不是std::string
,date::time_zone const*
。
在三大平台(llvm / gcc / MSVS)上,最粗糙的system_clock::time_point
是微秒,符合您的精确目标。
第一步是创建一个zoned_time
,它是time_point
与time_zone
的配对。从这一个可以获得local_time
。
floor<days>
会将time_point
的精度截断为days
。如果从精细度time_point
中减去日精度time_point
,则获得当地时间。
如果您将此本地时间存储在chrono::duration
代表double
且期限为1天的情况下,那么您将获得Excel时间格式
这可以像:
一样使用int
main()
{
using namespace date;
using namespace std::chrono;
std::cout << std::fixed << std::setprecision(9);
std::cout << GetTime(sys_seconds{1528480019s}, locate_zone("America/Chicago")) << '\n';
zoned_time<system_clock::duration> zt{"America/New_York",
local_days{2018_y/6/8} + 13h + 46min + 58s};
std::cout << GetTime(zt.get_sys_time(), zt.get_time_zone()) << '\n';
}
输出:
0.532627315
0.574282407
上面,我努力尽可能接近您现有的API。但是,如果您采用此库,则可以通过采用“更原生”的API使其更简单,更高效:
std::chrono::duration<double, date::days::period>
GetTime(const date::zoned_time<std::chrono::system_clock::duration>& zt)
{
using namespace date;
auto lt = zt.get_local_time();
return lt - floor<days>(lt);
}
现在GetTime
只接受zoned_time<system_clock::duration>
类型的单个参数,并返回duration<double, days::period>
。 GetTime
要做的就是将本地时间截断为天精度,减去时间以获取时间。
main
中的演示也得到了简化:
std::cout << GetTime({"America/Chicago", sys_seconds{1528480019s}}).count() << '\n';
std::cout << GetTime({"America/New_York",
local_days{2018_y/6/8} + 13h + 46min + 58s}).count() << '\n';
并提供与以前相同的输出。