日期和时间工具

本文最后更新于:2022年3月19日 凌晨

此文来源于👉日期和时间工具 - cppreference.com

日期和时间工具#

#

  • 时钟
  • 时长
  • 时间点

时钟#

system_clock(C++11) 来自系统范畴实时时钟的挂钟时间 (类)
steady_clock(C++11) 决不会调整的单调时钟 (类)
high_resolution_clock(C++11) 拥有可用的最短嘀嗒周期的时钟 (类)
is_clockis_clock_v(C++20) 确定类型是否为时钟 (Clock) (类模板) (变量模板)
utc_clock(C++20) 协调世界时 (UTC) 的时钟 (Clock) (类)
tai_clock(C++20) 国际原子时 (TAI) 的时钟 (Clock) (类)
gps_clock(C++20) GPS 时间的时钟 (Clock) (类)
file_clock(C++20) 用于文件时间时钟 (Clock) (typedef)
local_t(C++20) 表示本地时间的伪时钟

时间点#

时间点是从特定时钟的纪元开始经过的时间时长。

定义于头文件 <chrono>
定义于命名空间 std::chrono
time_point(C++11) 时间中的点 (类模板)
clock_time_conversion(C++20) 定义如何转换一个时钟的时间点为另一个的特性类 (类模板)
clock_cast(C++20) 转换一个时钟的时间点为另一个 (函数模板)

时长#

时长由时间跨度组成,定义为某时间单位的某个计次数。例如,“ 42 秒”可表示为由 42 个 1 秒时间点位的计次所组成的时长。

定义于头文件 <chrono>
定义于命名空间 std::chrono
duration(C++11) 时间区间 (类模板)

当天时刻#

hh_mm_ss 只要可能就将表示自午夜起经过时间的时长分割成时、分、秒和秒的小数部分。它主要是格式化工具。

定义于头文件 <chrono>
定义于命名空间 std::chrono
hh_mm_ss(C++20) 表示当天时刻 (类模板)
is_am is_pm make12 make24(C++20) 在 12 时和 24 时格式当天时刻之间翻译 (函数)

日历#

定义于头文件 <chrono>
定义于命名空间 std::chrono
last_spec(C++20) 指示一个月中最后日期或星期的标签类 (类)
day(C++20) 表示月之日期 (类)
month(C++20) 表示年之月份 (类)
year(C++20) 表示格里高利历中的年 (类)
weekday(C++20) 表示格里高利历中星期之日 (类)
weekday_indexed(C++20) 表示月份的第 n 个 weekday (类)
weekday_last(C++20) 表示月份的最后一个 weekday (类)
month_day(C++20) 表示特定 month 的特定 day (类)
month_day_last(C++20) 表示特定 month 的最后一日 (类)
month_weekday(C++20) 表示特定 month 的第 n 个 weekday (类)
month_weekday_last(C++20) 表示特定 month 的最后一个 weekday (类)
year_month(C++20) 表示特定 year 的特定 month (类)
year_month_day(C++20) 表示特定的 yearmonthday (类)
year_month_day_last(C++20) 表示特定 yearmonth 的最后一日 (类)
year_month_weekday(C++20) 表示特定 yearmonth 的第 n 个 weekday (类)
year_month_weekday_last(C++20) 表示特定 yearmonth 的最后一个 weekday (类)
operator/(C++20) 创建格里高利历日期的约定语法 (函数)

时区#

定义于头文件 <chrono>
定义于命名空间 std::chrono
tzdb(C++20) 描述 IANA 时区数据库的副本 (类)
tzdb_list(C++20) 表示 tzdb 的链表 (类)
get_tzdbget_tzdb_listreload_tzdbremote_version(C++20) 访问和控制全球时区数据库信息 (函数)
locate_zone(C++20) 定位基于其名称的 time_zone (函数)
current_zone(C++20) 返回当前的 time_zone (函数)
time_zone(C++20) 表示时区 (类)
sys_info(C++20) 表示在特定时间点的关于时区的信息 (类)
local_info(C++20) 表示关于从本地时间转换到 UNIX 时间的信息 (类)
choose(C++20) 选择应如何解析歧义的本地时间 (枚举)
zoned_traits(C++20) zoned_time 所用的时区指针的特性类 (类模板)
zoned_time(C++20) 表示时区和时间点 (类)
leap_second(C++20) 含有关于插入闰秒的信息 (类)
time_zone_link(C++20) 表示时区的替用名 (类)
nonexistent_local_time(C++20) 抛出以报告本地时间不存在的异常 (类)
ambiguous_local_time(C++20) 抛出以报告本地时间有歧义的异常 (类)

时钟#

std::chrono::system_clock::now()#

返回表示当前时间的时间点。

#include <iostream>
#include <vector>
#include <numeric>
#include <chrono>
 
volatile int sink;
int main()
{
    for (auto size = 1ull; size < 1000000000ull; size *= 100) {
        // 记录开始时间
        auto start = std::chrono::system_clock::now();
        // 做一些工作
        std::vector<int> v(size, 42);
        sink = std::accumulate(v.begin(), v.end(), 0u); // 确保其副效应
        // 记录结束时间
        auto end = std::chrono::system_clock::now();
        std::chrono::duration<double> diff = end-start;
        std::cout << "Time to fill and iterate a vector of " 
                  << size << " ints : " << diff.count() << " s\n";
    }
}

std::chrono::steady_clock::now()#

返回表示当前时间的时间点。

#include <iostream>
#include <vector>
#include <numeric>
#include <chrono>
 
volatile int sink;
int main()
{
    for (auto size = 1ull; size < 1000000000ull; size *= 100) {
        // 记录开始时间
        auto start = std::chrono::steady_clock::now();
        // 做一些工作
        std::vector<int> v(size, 42);
        sink = std::accumulate(v.begin(), v.end(), 0u); // 确保其副效应
        // 记录结束时间
        auto end = std::chrono::steady_clock::now();
        std::chrono::duration<double> diff = end-start;
        std::cout << "Time to fill and iterate a vector of " 
                  << size << " ints : " << diff.count() << " s\n";
    }
}

对时长度量使用 steady_clock ,对壁钟时间使用 system_clock

std::chrono::utc_clock::now()#

返回表示当前时间的时间点

std::chrono::tai_clock::now()#

返回表示当前时间的时间点。

std::chrono::gps_clock::now()#

返回表示当前时间的时间点。

std::chrono::file_clock::now()#

返回表示当前时间的时间点。

时间点#

时间点是从特定时钟的纪元开始经过的时间时长。

std::chrono::time_point<std::chrono::system_clock>#

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>
 
void slow_motion()
{
    static int a[] {1,2,3,4,5,6,7,8,9,10,11,12};
    while (std::ranges::next_permutation(a).found)
    { } // 生成 12! 个排列
}
 
int main()
{
    using namespace std::literals; // 允许用 24h 、 1ms 、 1s 代替对应的
                                   // std::chrono::hours(24) 等待
 
    const std::chrono::time_point<std::chrono::system_clock> now =
        std::chrono::system_clock::now();
        // “生产代码”可以简化为:
        // const auto now = std::chrono::system_clock::now();
 
    const std::time_t t_c = std::chrono::system_clock::to_time_t(now - 24h);
    std::cout << "24 hours ago, the time was "
              << std::put_time(std::localtime(&t_c), "%F %T.\n") << std::flush;
 
    const std::chrono::time_point<std::chrono::steady_clock> start =
        std::chrono::steady_clock::now();
        // “现实生活”的替用写法会是:
        // const auto start = std::chrono::steady_clock::now();
 
    slow_motion();
 
    const auto end = std::chrono::steady_clock::now();
 
    std::cout
      << "Slow calculations took "
      << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << "µs ≈ "
      << (end - start) / 1ms << "ms ≈ " // 几乎等价于以上形式,
      << (end - start) / 1s << "s.\n";  // 但分别使用毫秒和秒
}

时长#

摘录自MSVC标准库

using nanoseconds = duration<long long, nano> 纳秒 std::chrono::nanoseconds
using microseconds = duration<long long, micro> 微秒 std::chrono::microseconds
using milliseconds = duration<long long, milli> 毫秒 std::chrono::milliseconds
using seconds = duration 秒 std::chrono::seconds
using minutes = duration<int, ratio<60>> 分钟 std::chrono::minutes
using hours = duration<int, ratio<3600>> 小时 std::chrono::hours
using days = duration<int, ratio_multiply<ratio<24>, hours::period>> 天 std::chrono::days
using weeks = duration<int, ratio_multiply<ratio<7>, days::period>> 周 std::chrono::weeks
using years = duration<int, ratio_multiply<ratio<146097, 400>, days::period>> 年 std::chrono::years
using months = duration<int, ratio_divide<years::period, ratio<12>>> 月 std::chrono::months

注意:到 hours 为止的每个预定义时长类型至少涵盖 ±292 年的范围。

#include <iostream>
#include <chrono>
 
constexpr auto year = 31556952ll; // 格里高利历年的平均秒数
 
int main()
{
    using shakes = std::chrono::duration<int, std::ratio<1, 100000000>>;
    using jiffies = std::chrono::duration<int, std::centi>;
    using microfortnights = std::chrono::duration<float, std::ratio<14*24*60*60, 1000000>>;
    using nanocenturies = std::chrono::duration<float, std::ratio<100*year, 1000000000>>;
 
    std::chrono::seconds sec(1);
 
    std::cout << "1 second is:\n";
 
    // 无精度损失的整数尺度转换:无转型
    std::cout << std::chrono::microseconds(sec).count() << " microseconds\n"
              << shakes(sec).count() << " shakes\n"
              << jiffies(sec).count() << " jiffies\n";
 
    // 有精度损失的整数尺度转换:需要转型
    std::cout << std::chrono::duration_cast<std::chrono::minutes>(sec).count()
              << " minutes\n";
 
    // 浮点尺度转换:无转型
    std::cout << microfortnights(sec).count() << " microfortnights\n"
              << nanocenturies(sec).count() << " nanocenturies\n";
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!