代码之家  ›  专栏  ›  技术社区  ›  Museful

从编译时已知的日历日期创建“std::chrono::time\u point”

  •  2
  • Museful  · 技术社区  · 6 年前

    This std::chrono::time_point ,如下所示:

    std::tm tm = {};
    std::stringstream ss("Jan 9 2014 12:35:34");
    ss >> std::get_time(&tm, "%b %d %Y %H:%M:%S");
    auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
    

    如果我想创建一个 标准::时间::时间点

    2 回复  |  直到 6 年前
        1
  •  6
  •   Howard Hinnant    6 年前

    是的,您可以在编译时完成整个计算,创建一个 constexpr system_clock::time_point Howard Hinnant's date/time library .

    #include "date/date.h"
    #include <chrono>
    
    int
    main()
    {
        using namespace date;
        using namespace std::chrono;
        constexpr system_clock::time_point tp = sys_days{January/9/2014} + 12h + 35min + 34s;
        static_assert(tp == system_clock::time_point{1389270934s}, "");
    }
    

    这是假设日期/时间是UTC。如果不是这样,则必须手动添加/减去UTC偏移量。由于时区规则总是随着政客们的心血来潮而改变,制定时区规则的希望渺茫 constexpr

    这个程序也会通过下拉的方式传送到C++ 20。 #include "date/date.h" using namespace date; . 同时使用 要求C++ 14 肌肉。C++ 11 常量表达式 常量表达式 static_assert ).

        2
  •  9
  •   TrentP    5 年前

    然而,如果一个人还没有c++20并且希望避免添加更多的外部库,那么这个答案仍然有用。

    您可以设置 std::tm 分别在初始值设定项中,以避免解析字符串。

    // 9th January, 2014
    #define DAY 9
    #define MONTH 1
    #define YEAR 2014
    
    std::tm tm = { /* .tm_sec  = */ 0,
                   /* .tm_min  = */ 0,
                   /* .tm_hour = */ 0,
                   /* .tm_mday = */ (DAY),
                   /* .tm_mon  = */ (MONTH) - 1,
                   /* .tm_year = */ (YEAR) - 1900,
                 };
    tm.tm_isdst = -1; // Use DST value from local time zone
    auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
    

    指定的初始化器是注释出来的,因为它们只在C++ 20中可用(尽管GCC已经支持了一些琐碎指定的初始化器作为一段时间的扩展,并且将与这种情况一起工作)。如果有一个C++ 20指定初始化器,并且在目标日期需要午夜,则可以省略初始化为零的字段。

    值得注意的是 mktime 将解释 tm 作为 tm_isdst 如果未设置为-1,则它将是本地标准时间,即使在指定的时间内本地时区使用夏时制(夏令时)。

    从时间点生成UTC时间点 标准::tm ,一个与您的示例共享的问题,将在其他问题中解决,例如 Easy way to convert a struct tm (expressed in UTC) to time_t type

        3
  •  0
  •   Clare Macrae    5 年前

    这是C++ 11和以上的工作原理:

    #include <chrono>
    
    std::chrono::system_clock::time_point
    createDateTime(int year,
                   int month,
                   int day,
                   int hour,
                   int minute,
                   int second) // these are UTC values
    {
        tm timeinfo1 = tm();
        timeinfo1.tm_year = year - 1900;
        timeinfo1.tm_mon = month - 1;
        timeinfo1.tm_mday = day;
        timeinfo1.tm_hour = hour;
        timeinfo1.tm_min = minute;
        timeinfo1.tm_sec = second;
        tm timeinfo = timeinfo1;
        time_t tt = toUTC(timeinfo);
        return std::chrono::system_clock::from_time_t(tt);
    }
    
    time_t toUTC(std::tm& timeinfo)
    {
    #ifdef _WIN32
        std::time_t tt = _mkgmtime(&timeinfo);
    #else
        time_t tt = timegm(&timeinfo);
    #endif
        return tt;
    }
    

    取自 ApprovalTests/utilities/DateUtils.cpp