我编写了以下函数来接收时间点并返回一个毫秒的ISO字符串:
std::string TimePointToISOString(const std::chrono::time_point<std::chrono::system_clock>& time)
{
std::time_t rawTime = std::chrono::system_clock::to_time_t(time);
struct tm timeinfo;
localtime_s(&timeinfo, &rawTime);
std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(time.time_since_epoch());
std::size_t frac_seconds = ms.count() % 1000;
char buffer[32];
std::strftime(buffer, 32, "%FT%TZ", &timeinfo);
std::string bufferStr(buffer);
std::stringstream ss;
ss << bufferStr.substr(0, 19) << "." << std::setw(3) << std::setfill ('0') << frac_seconds << bufferStr.substr(20);
return ss.str();
}
我曾经使用localtime()
函数在Linux上运行它,没有任何问题。现在我正在迁移到Windows / VS2012,并且编译器建议更改localtime()
以获得更安全的localtime_s()
,立即完成。
转换后,strftime
调用在运行时崩溃,并出现以下错误:
Expression: ("Invalid format directive", 0)
编译运行正常。帮助欣赏,了解这里发生了什么。我猜想一些我不会注意到的简单......
答案 0 :(得分:4)
在C99中添加了%F
和%T
次转化,而VS 2012仅支持C89。
虽然它仍然没有尝试支持所有C99,但我相信VS 2015增加了更多(特别是C99库函数,这也是C ++ 11的一部分),这应该可以正常使用它。
如果您需要继续使用较旧的编译器/库,%F和%T基本上都是&#34;快捷方式&#34;对于C89中已经支持的某些格式。如果我正确地阅读了要求,则以下内容应相同:
std::strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &timeinfo);
顺便说一句,如果您的编译器支持C ++ 11,那么使用std::put_time
代替strftime
通常会更容易和更清晰。
答案 1 :(得分:2)
这是一个很好的问题(upvoted)。而Jerry Coffin的回答是一个很好的答案(也是赞成的)。这个答案是关于添加有关替代开源解决方案的更多信息,该解决方案已知可用于VS-2013及更高版本,gcc和clang。此备选方案将向TimePointToISOString
生成相同的输出。为了区分它,我给它起了另一个名字:to_local_string
:
std::string
to_local_string(const std::chrono::system_clock::time_point& time)
{
using namespace date;
auto zone = current_zone();
auto local = floor<std::chrono::milliseconds>(zone->to_local(time).first);
auto dp = floor<days>(local);
year_month_day ymd = dp;
std::stringstream ss;
ss << ymd << 'T' << make_time(local-dp);
return ss.str();
}
这使用此处的时区数据库解析器:
https://github.com/HowardHinnant/date
并在此处记录:
http://howardhinnant.github.io/tz.html
这是IANA Timezone database的解析器,用于简单地找到本地时区的UTC偏移量。找到本地time_point(存储为std::chrono::system_clock::time_point
)后,使用this library将其分解为字段类型年/月/日/小时/分钟/秒/毫秒,其实现位于同一位置github网站。
我刚在同一时间点上同时运行TimePointToISOString
和to_local_string
,输出结果是:
2016-03-23T22:54:52.626
2016-03-23T22:54:52.626