c++ - localtime_s 和 strftime 用法构建 ISO 时间字符串

标签 c++ c++11 strftime c++-chrono localtime

我编写了以下接收时间点并返回带毫秒的 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();
    }

我曾经在 Linux 上使用 localtime() 函数运行它,完全没有问题。现在我正在迁移到 Windows/VS2012,编译器建议更改 localtime() 以获得更安全的 localtime_s(),立即完成。

转换后,strftime 调用确实在运行时崩溃并出现以下错误:

Expression: ("Invalid format directive", 0)

编译运行良好。感谢帮助找出这里发生了什么。我想是一些我没注意到的简单事情...

最佳答案

C99中加入了%F%T转换,VS 2012只支持C89。

虽然它仍然没有尝试支持所有 C99,但我相信 VS 2015 添加了足够多的内容(尤其是 C99 库函数,它们也是 C++11 的一部分),这应该可以很好地工作。

如果您需要继续使用旧的编译器/库,%F 和 %T 基本上都是 C89 已经支持的某些格式的“快捷方式”。如果我正确阅读了要求,则以下内容应该是等效的:

std::strftime(buffer, 32, "%Y-%m-%dT%H:%M:%SZ", &timeinfo);

顺便说一句,如果你的编译器支持 C++11,使用 std::put_time 通常会更容易、更简洁。而不是 strftime

关于c++ - localtime_s 和 strftime 用法构建 ISO 时间字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36190924/

相关文章:

c++ - 如何获取 `std::basic_string<CustomClass>`进行编译?

c++ - 派生可变参数类模板的调用函数模板重载

iphone - 使用 strftime 将 NSDate 转换为字符串

python - 使用 strftime 的 sqlite 查询始终返回 None

c# - SWIG C++ 到 C# 错误无法找到入口点 SWIGRegisterExceptionCallbacks_xxxx

c++ - 声明继承的模板化对象并将它们推回 vector - 优雅的方式?

C++11 与 R 和 Rcpp : supported by CRAN policies?

php - 为什么 strftime ('%G' , strtotime ('2017-01-01' )) 产生 2016 年?

c++ - C++ HTTPS 库在性能(例如内存占用、CPU 时间等)方面如何比较?

c++ - Ubuntu Make 文件错误