首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++11替代localtime_r

C++11替代localtime_r
EN

Stack Overflow用户
提问于 2011-09-06 00:37:55
回答 2查看 20.4K关注 0票数 39

C++用strftime定义时间格式化函数,这需要一个struct tm“分解时间”记录。然而,C语言和C++03语言没有提供线程安全的方法来获得这样的记录;整个程序只有一个主struct tm

在C++03中,这或多或少是可以的,因为语言不支持多线程;它只是支持支持多线程的平台,然后提供了诸如POSIX localtime_r之类的工具。

C++11还定义了新的时间实用程序,它与未分解的time_t类型的接口,这将用于重新初始化全局struct tm。但获得time_t并不是问题所在。

我是遗漏了什么,还是这个任务仍然需要依赖POSIX?

编辑:这里是一些变通代码。它维护与提供::localtime_r的多线程环境和只提供std::localtime的单线程环境的兼容性。它可以很容易地调整,以检查其他功能,如posix::localtime_r::localtime_s或什么-您。

代码语言:javascript
运行
复制
namespace query {
    char localtime_r( ... );

    struct has_localtime_r
        { enum { value = sizeof localtime_r( std::declval< std::time_t * >(), std::declval< std::tm * >() )
                        == sizeof( std::tm * ) }; };


    template< bool available > struct safest_localtime {
        static std::tm *call( std::time_t const *t, std::tm *r )
            { return localtime_r( t, r ); }
    };

    template<> struct safest_localtime< false > {
        static std::tm *call( std::time_t const *t, std::tm *r )
            { return std::localtime( t ); }
    };
}
std::tm *localtime( std::time_t const *t, std::tm *r )
    { return query::safest_localtime< query::has_localtime_r::value >().call( t, r ); }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-06 02:44:14

你什么都没错过。

下一个C标准(可能在今年发布)已在附件K中作了界定:

代码语言:javascript
运行
复制
struct tm *localtime_s(const time_t * restrict timer,
                       struct tm * restrict result);

这个新功能是线程安全的!但不要太高兴。有两个主要问题:

  1. localtime_s对C11.

的可选扩展。

  1. C++11引用C99,而不是C11。local_time_s不存在于C++11中,可选与否。

更新

在我回答这个问题后的4年里,我也对C++工具在这个领域的糟糕设计感到沮丧。我的动机是创建现代的C++工具来处理这个问题:

http://howardhinnant.github.io/date/tz.html

代码语言:javascript
运行
复制
#include "tz.h"
#include <iostream>

int
main()
{
    using namespace date;
    auto local_time = make_zoned(current_zone(), std::chrono::system_clock::now());
    std::cout << local_time << '\n';
}

这只是我的输出:

2015年-10-28 14:17:31.980135

local_time是表示本地时间的std::chrono::system_clock::time_pointtime_zone的配对。

存在将std::chrono::system_clock::time_point分解为人类可读的字段类型的实用工具,例如年、月、日、小时、分钟、秒和子秒。以下是重点介绍(非时区)部分的演示文稿:

https://www.youtube.com/watch?v=tzyGjOm8AKo

所有这些当然都是线程安全的(它是现代的C++)。

更新2

上面的内容现在是C++20的一部分,它的语法略有改变:

代码语言:javascript
运行
复制
#include <chrono>
#include <iostream>

int
main()
{
    namespace chr = std::chrono;

    chr::zoned_time local_time{chr::current_zone(), chr::system_clock::now()};
    std::cout << local_time << '\n';
}
票数 29
EN

Stack Overflow用户

发布于 2022-06-17 19:10:36

下面的回答指出了mktime()的一个关键细节(它是处理struct tm的唯一线程安全函数,甚至在C99之前):

下面是localtime_rlocaltime_s的一个可移植的替代方案

代码语言:javascript
运行
复制
//  localtime_s(&startTm, &startTimeT);
tm startTm{};
startTm.tm_isdst = -1;
startTm.tm_year = 122;
auto refTimeT = mktime(&startTm);
startTm.tm_sec += startTimeT - refTimeT;
mktime(&startTm);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7313919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档