简介

  • 标准库相关笔记

持续时间的表示(Duration Representation)

  • 持续时间在std::chrono中是以一种非常直观的方式表示的,它反映了我们对时间的基本理解:时间是连续的,并且可以以不同的单位来衡量。在std::chrono中,持续时间是通过两个模板参数来定义的:一个是用于存储时间值的底层类型(如int64_t),另一个是时间单位(如秒、毫秒)。

C++ 标准库是什么

C++ 标准库中的 <chrono> 是用于处理时间相关操作的头文件,提供了时间点(time_point)和持续时间(duration)的类模板,以及用于操作时间的各种函数和工具。

主要包括以下内容:

时间点(time_point)和持续时间(duration):

  • std::chrono::time_point 代表时间的点,通常表示自某个特定时钟起的时间。例如,std::chrono::system_clock::time_point 表示系统时钟的时间点。
  • std::chrono::duration 表示时间间隔的持续时间,可以用于表示一段时间的长度。例如,std::chrono::duration<int> 表示以整数单位的时间段。

时钟(Clocks):

  • std::chrono::system_clock 代表系统时钟,提供了从 Epoch(通常是 1970 年 1 月 1 日)起的时间点。
  • std::chrono::steady_clock 代表一个单调递增的时钟,不受系统时间调整影响,适合测量时间间隔。
  • std::chrono::high_resolution_clock 代表一个高分辨率的时钟,提供了更高精度的计时。

时间相关工具和函数:

  • 时间单位转换: 提供了 duration_cast 函数用于不同时间单位之间的转换。
  • 时间点的算术运算: 可以对时间点进行加减运算。
  • 定时器操作: 可以用于实现定时器,比如 std::this_thread::sleep_forstd::this_thread::sleep_until
  • 时钟的特性和属性: 可以获取时钟的特性,如时钟的最小精度、是否稳定等。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <chrono>

int main() {
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();

    // 时间点转换为时间戳
    std::time_t now_c = std::chrono::system_clock::to_time_t(now);

    // 打印当前时间
    std::cout << "Current time: " << std::ctime(&now_c);

    // 创建持续时间并延迟一段时间
    std::chrono::milliseconds delay(1000);
    std::this_thread::sleep_for(delay);

    return 0;
}

<chrono> 提供了一种标准化的时间处理方式,可用于测量和管理时间,执行定时操作以及进行时间单位转换。

C++ 标准库 详解

<chrono> 是 C++ 标准库中用于处理时间相关操作的头文件,自 C++11 起引入。它提供了时间点(time_point)、持续时间(duration)、时钟(clock)以及与时间相关的函数和工具,使得在 C++ 中对时间进行精确测量和处理变得更加方便和标准化。

重要的类型和类:

  • std::chrono::time_point 表示时间的点,在特定时钟下的时间。例如,std::chrono::system_clock::time_point 表示系统时钟的时间点。
  • std::chrono::duration 表示时间间隔的持续时间,可以用于表示一段时间的长度。例如,std::chrono::duration<int> 表示以整数单位的时间段。

重要的时钟(Clocks):

  • std::chrono::system_clock 代表系统时钟,提供了从 Epoch(通常是 1970 年 1 月 1 日)起的时间点。
  • std::chrono::steady_clock 代表一个单调递增的时钟,不受系统时间调整影响,适合测量时间间隔。
  • std::chrono::high_resolution_clock 代表一个高分辨率的时钟,提供了更高精度的计时。

主要函数和工具:

  • 时间单位转换: 提供了 std::chrono::duration_cast 函数用于不同时间单位之间的转换。
  • 时间点的算术运算: 可以对时间点进行加减运算。
  • 定时器操作: 可以用于实现定时器,比如 std::this_thread::sleep_forstd::this_thread::sleep_until
  • 获取时间点: 提供了 std::chrono::system_clock::now() 用于获取当前时间点。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <chrono>

int main() {
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();

    // 时间点转换为时间戳
    std::time_t now_c = std::chrono::system_clock::to_time_t(now);

    // 打印当前时间
    std::cout << "Current time: " << std::ctime(&now_c);

    // 创建持续时间并延迟一段时间
    std::chrono::milliseconds delay(1000);
    std::this_thread::sleep_for(delay);

    return 0;
}

<chrono> 提供了一种标准化的时间处理方式,可用于测量和管理时间,执行定时操作以及进行时间单位转换。它的引入使得在 C++ 中对时间进行处理更加方便和跨平台。

C++ 标准库 常用函数

C++ <chrono> 标准库提供了用于处理时间的功能,包括时间点(time points)、时间间隔(durations)、时钟(clocks)等。以下是一些 <chrono> 标准库中常用的函数和类:

类和类型

  1. std::chrono::duration:表示时间间隔的类型。例如 std::chrono::duration<int> 表示以整数秒为单位的时间间隔。

  2. std::chrono::time_point:表示特定时钟的时间点。它由时钟和持续时间构成。

  3. std::chrono::system_clock:提供当前时间,并使用 UNIX 时间(1970 年 1 月 1 日午夜起的秒数)作为其时间起点。

  4. std::chrono::steady_clock:提供一个稳定的时钟,用于测量时间间隔,不受系统时间调整的影响。

  5. std::chrono::high_resolution_clock:提供高分辨率时钟,尽可能提供最高精度的计时,但其精度因平台而异。

函数

  1. std::chrono::duration_cast:用于将一个时间间隔类型转换为另一个时间间隔类型。

    1
    
    auto result = std::chrono::duration_cast<std::chrono::minutes>(some_duration);
    
  2. std::chrono::time_point_cast:用于将一个时间点类型转换为另一个时间点类型。

    1
    
    auto result = std::chrono::time_point_cast<std::chrono::hours>(some_time_point);
    
  3. std::chrono::system_clock::now:获取当前时间点。

    1
    
    auto current_time = std::chrono::system_clock::now();
    
  4. std::chrono::steady_clock::now:获取当前稳定时钟的时间点。

    1
    
    auto current_time = std::chrono::steady_clock::now();
    
  5. std::chrono::duration 中的各种算术运算:例如加法、减法、乘法和除法,用于处理时间间隔之间的运算。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <chrono>

int main() {
    // 获取当前系统时间点
    auto start_time = std::chrono::system_clock::now();

    // 模拟一段程序执行时间
    std::cout << "Working..." << std::endl;
    for (int i = 0; i < 1000000; ++i) {
        // 做一些计算
    }

    // 获取结束时间点
    auto end_time = std::chrono::system_clock::now();

    // 计算程序执行时间间隔
    auto duration = end_time - start_time;
    std::cout << "Program execution time: " << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << " milliseconds\n";

    return 0;
}

以上是 C++ <chrono> 标准库中一些常用的函数和类,可以用于时间点和时间间隔的操作和管理。

std::chrono::duration

std::chrono::duration 是 C++ <chrono> 标准库中表示时间间隔的类模板。它表示一个时间段,可以用于测量不同时间点之间的时间差,以及进行时间单位之间的转换。std::chrono::duration 的模板定义如下:

1
2
template <class Rep, class Period = std::ratio<1>>
class duration;
  • Rep:表示持续时间的类型,通常是一个整数类型,用于存储时间长度。
  • Period:表示时间单位的类型,通常是 std::ratio 类型,它定义了时间间隔的基本单位。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <chrono>

int main() {
    // 定义一个持续时间为10秒的duration
    std::chrono::duration<int> ten_seconds(10);

    // 获取duration的值和单位
    std::cout << "ten_seconds: " << ten_seconds.count() << " seconds" << std::endl;

    // 定义一个浮点型持续时间,表示0.5秒
    std::chrono::duration<double> half_second(0.5);

    // 获取duration的值和单位
    std::cout << "half_second: " << half_second.count() << " seconds" << std::endl;

    // 进行duration之间的加法操作
    auto total_duration = ten_seconds + half_second;

    // 获取总持续时间的值和单位
    std::cout << "total_duration: " << total_duration.count() << " seconds" << std::endl;

    return 0;
}

在示例中,std::chrono::duration 被用来表示不同的时间间隔,可以通过 count() 函数获取其持续时间的值,并且支持多种时间间隔的算术操作,如加法、减法等。

std::chrono::time_point

std::chrono::time_point 是 C++ <chrono> 标准库中的类模板,用于表示特定时钟(Clock)的时间点。它结合了时钟(Clock)和持续时间(Duration),可以表示从时钟的起点开始经过的时间。std::chrono::time_point 的模板定义如下:

1
2
template <class Clock, class Duration = typename Clock::duration>
class time_point;
  • Clock:表示时钟类型,例如 std::chrono::system_clockstd::chrono::steady_clock 等。
  • Duration:表示时间间隔的类型,通常是 std::chrono::duration 类型。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <chrono>

int main() {
    // 使用 system_clock 获取当前时间点
    std::chrono::time_point<std::chrono::system_clock> current_time = std::chrono::system_clock::now();

    // 使用 steady_clock 获取当前时间点
    std::chrono::time_point<std::chrono::steady_clock> start_time = std::chrono::steady_clock::now();

    // 进行一些操作...

    // 获取另一个时间点并计算时间间隔
    std::chrono::time_point<std::chrono::steady_clock> end_time = std::chrono::steady_clock::now();
    std::chrono::duration<double> duration = end_time - start_time;

    // 输出时间间隔
    std::cout << "Duration: " << duration.count() << " seconds" << std::endl;

    return 0;
}

在示例中,std::chrono::time_point 被用于存储不同时钟类型(std::chrono::system_clockstd::chrono::steady_clock)的时间点。可以使用 now() 函数获取当前时间点,也可以进行时间点之间的算术运算(例如计算时间间隔)。

std::chrono::system_clock

std::chrono::system_clock 是 C++ <chrono> 标准库中的时钟类型,用于提供当前系统时间和日期。它是一个基于实时时钟的时钟类,使用的时钟起点通常是 UNIX 时间(1970 年 1 月 1 日午夜起的秒数)。std::chrono::system_clock 提供了获取当前时间的方法。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <chrono>
#include <ctime>

int main() {
    // 获取当前系统时间点
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();

    // 将时间点转换为时间戳(秒数)
    std::time_t timestamp = std::chrono::system_clock::to_time_t(now);

    // 输出时间戳
    std::cout << "Current timestamp: " << timestamp << std::endl;

    // 将时间戳转换回时间点
    std::chrono::system_clock::time_point time_from_timestamp = std::chrono::system_clock::from_time_t(timestamp);

    // 检查时间点是否相同
    if (time_from_timestamp == now) {
        std::cout << "Time points are equal." << std::endl;
    } else {
        std::cout << "Time points are not equal." << std::endl;
    }

    return 0;
}

在示例中,std::chrono::system_clock 被用于获取当前系统时间点 (now),并且可以将时间点转换为时间戳 (std::time_t),以及将时间戳转换回时间点。这允许在不同的时钟表示之间进行转换和比较。

std::chrono::steady_clock

std::chrono::steady_clock 是 C++ <chrono> 标准库中的时钟类型,用于提供稳定、不受系统时间调整影响的时钟。它用于测量时间间隔,适合于需要精确计时而不受系统时间调整(例如时间同步或夏令时变化)影响的场景。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <chrono>

int main() {
    // 获取起始时间点
    std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now();

    // 模拟一段程序执行时间
    for (int i = 0; i < 1000000; ++i) {
        // 做一些计算
    }

    // 获取结束时间点
    std::chrono::steady_clock::time_point end_time = std::chrono::steady_clock::now();

    // 计算程序执行时间间隔
    std::chrono::duration<double> duration = end_time - start_time;

    // 输出程序执行时间
    std::cout << "Program execution time: " << duration.count() << " seconds" << std::endl;

    return 0;
}

在这个示例中,std::chrono::steady_clock 被用于获取程序开始和结束时的时间点,并计算两个时间点之间的持续时间。这种时钟不受系统时间调整的影响,适用于需要精确计时的场景,比如性能测试或计时要求较高的应用程序。

std::chrono::high_resolution_clock

std::chrono::high_resolution_clock 是 C++ <chrono> 标准库中的时钟类型,提供了高精度计时功能,尽可能提供最高分辨率的时间测量。然而,精度和实际分辨率可能因平台和实现而异。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <chrono>

int main() {
    // 获取起始时间点
    auto start_time = std::chrono::high_resolution_clock::now();

    // 模拟一段程序执行时间
    for (int i = 0; i < 1000000; ++i) {
        // 做一些计算
    }

    // 获取结束时间点
    auto end_time = std::chrono::high_resolution_clock::now();

    // 计算程序执行时间间隔
    auto duration = end_time - start_time;

    // 输出程序执行时间
    std::cout << "Program execution time: " << std::chrono::duration_cast<std::chrono::microseconds>(duration).count() << " microseconds" << std::endl;

    return 0;
}

在示例中,std::chrono::high_resolution_clock 被用于测量程序执行时间。需要注意的是,尽管这个时钟通常提供较高的分辨率,但实际精度取决于系统的支持以及硬件平台。因此,在不同的系统上,精度和分辨率可能会有所不同。

std::chrono::duration_cast

std::chrono::duration_cast<chrono> 标准库中的函数,用于执行 std::chrono::duration 类型之间的转换。它允许将一个持续时间(duration)对象从一种单位转换为另一种单位。常用于从高精度单位(例如纳秒或微秒)转换为较低精度单位(例如秒或毫秒)。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <chrono>

int main() {
    // 创建一个高精度的持续时间(纳秒)
    std::chrono::nanoseconds ns_duration(123456789);

    // 将纳秒转换为毫秒
    std::chrono::milliseconds ms_duration = std::chrono::duration_cast<std::chrono::milliseconds>(ns_duration);

    // 输出转换后的持续时间
    std::cout << "Milliseconds: " << ms_duration.count() << " ms" << std::endl;

    return 0;
}

在上述示例中,std::chrono::duration_cast 将纳秒时间持续时间对象 ns_duration 转换为毫秒时间持续时间对象 ms_durationcount() 函数用于获取转换后持续时间的数值,并输出转换后的持续时间。这个函数非常有用,因为它允许你在不同时间单位之间进行安全和精确的转换。

std::chrono::time_point_cast

std::chrono::time_point_cast<chrono> 标准库中的函数,用于将 std::chrono::time_point 对象从一种时钟类型(Clock)转换为另一种时钟类型,并指定新的时间单位。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <chrono>

int main() {
    // 定义一个时间点,使用系统时钟
    std::chrono::system_clock::time_point sys_time = std::chrono::system_clock::now();

    // 将系统时钟时间点转换为稳定时钟时间点
    std::chrono::steady_clock::time_point steady_time = std::chrono::time_point_cast<std::chrono::steady_clock::duration>(sys_time);

    // 输出转换后的时间点(稳定时钟)
    std::cout << "Steady clock time: " << std::chrono::steady_clock::to_time_t(steady_time) << std::endl;

    return 0;
}

在这个示例中,std::chrono::time_point_cast 用于将系统时钟 (std::chrono::system_clock) 的时间点 sys_time 转换为稳定时钟 (std::chrono::steady_clock) 的时间点 steady_time。这种转换可能导致精度损失,因为不同的时钟可能具有不同的分辨率和特性。

std::chrono::system_clock::now

std::chrono::system_clock::now 是 C++ <chrono> 标准库中的函数,用于获取当前系统时间点,返回一个 std::chrono::time_point 对象,表示当前的系统时间。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <chrono>
#include <ctime>

int main() {
    // 获取当前系统时间点
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();

    // 将时间点转换为时间戳(秒数)
    std::time_t timestamp = std::chrono::system_clock::to_time_t(now);

    // 输出时间戳
    std::cout << "Current timestamp: " << timestamp << std::endl;

    return 0;
}

在这个示例中,std::chrono::system_clock::now() 用于获取当前系统时间点,然后通过 std::chrono::system_clock::to_time_t 将时间点转换为时间戳(秒数)以便输出。

std::chrono::steady_clock::now

std::chrono::steady_clock::now() 是 C++ <chrono> 标准库中的函数,用于获取当前稳定时钟(std::chrono::steady_clock)的时间点,返回一个 std::chrono::time_point 对象,表示当前的稳定时钟时间点。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <chrono>

int main() {
    // 获取当前稳定时钟时间点
    std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();

    // 进行一些操作...

    // 获取经过的时间间隔
    std::chrono::steady_clock::time_point later = std::chrono::steady_clock::now();
    std::chrono::duration<double> duration = later - now;

    // 输出经过的时间间隔
    std::cout << "Elapsed time: " << duration.count() << " seconds" << std::endl;

    return 0;
}

在这个示例中,std::chrono::steady_clock::now() 被用于获取程序执行时的稳定时钟时间点,然后可以计算程序执行所经过的时间间隔,这在需要精确计时而又不受系统时间变化影响的场景下非常有用。

std::chrono::duration

std::chrono::duration 是 C++ <chrono> 标准库中用于表示时间间隔的类模板。它能够表示一个时间段,即持续时间,以及可以用于测量不同时间点之间的时间差。

模板定义:

1
2
template<class Rep, class Period = std::ratio<1>>
class duration;
  • Rep:表示时间长度的类型,通常是一个整数类型,用于存储时间的长度。
  • Period:表示时间单位的类型,通常是 std::ratio 类型,定义了时间间隔的基本单位。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <chrono>

int main() {
    // 定义一个持续时间为 5 秒的 duration 对象
    std::chrono::duration<int> five_seconds(5);

    // 获取 duration 对象的值和单位
    std::cout << "Five seconds: " << five_seconds.count() << " seconds" << std::endl;

    // 定义一个浮点型持续时间,表示 2.5 秒
    std::chrono::duration<double> two_and_half_seconds(2.5);

    // 获取浮点型 duration 对象的值和单位
    std::cout << "Two and a half seconds: " << two_and_half_seconds.count() << " seconds" << std::endl;

    // 进行 duration 对象之间的加法操作
    auto total_duration = five_seconds + two_and_half_seconds;

    // 获取总持续时间的值和单位
    std::cout << "Total duration: " << total_duration.count() << " seconds" << std::endl;

    return 0;
}

在示例中,std::chrono::duration 用于表示不同的时间间隔,并可以通过 count() 函数获取持续时间的值。同时,std::chrono::duration 还支持不同时间间隔之间的算术操作,比如加法、减法等。

C++ 格式化输出年月日-时分秒

要格式化输出年月日-时分秒,你可以使用std::put_time函数。这个函数允许你将std::tm结构体转换为一个字符串,以指定的格式输出。下面是一个示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>
#include <chrono>

int main() {
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();

    // 将时间点转换为时间结构体
    std::time_t now_c = std::chrono::system_clock::to_time_t(now);
    std::tm* now_tm = std::localtime(&now_c);

    // 格式化输出年月日-时分秒
    std::cout << "当前时间:" << std::put_time(now_tm, "%Y-%m-%d %H:%M:%S") << std::endl;

    return 0;
}

这段代码使用std::put_timenow_tm结构体以指定格式输出,即”%Y-%m-%d %H:%M:%S”,其中:

  • %Y表示年份(四位数)
  • %m表示月份(两位数)
  • %d表示日期(两位数)
  • %H表示小时(24小时制,两位数)
  • %M表示分钟(两位数)
  • %S表示秒(两位数)

运行这段代码将输出当前的年月日-时分秒。

C++ std::chrono_literals 是什么

C++ 标准库中的 std::chrono_literals 是 C++11 引入的一个命名空间,用于提供方便的时间单位字面量,使得在编写时间相关代码时更加直观和易读。

这个命名空间中包含了各种时间单位的字面量,例如:

  • 1s:表示一秒钟。
  • 1ms:表示一毫秒(千分之一秒)。
  • 1us:表示一微秒(百万分之一秒)。
  • 1ns:表示一纳秒(十亿分之一秒)。

通过使用这些字面量,你可以在代码中直接使用自然的时间单位,而不需要手动计算时间的毫秒、微秒或纳秒值,从而提高了代码的可读性和可维护性。

例如,你可以这样使用 std::chrono_literals

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono_literals;

    auto duration = 100ms;
    std::cout << "Duration: " << duration.count() << " milliseconds" << std::endl;

    auto timeout = 5s;
    std::cout << "Timeout: " << timeout.count() << " seconds" << std::endl;

    return 0;
}

在上面的示例中,100ms5s 就是使用 std::chrono_literals 提供的时间单位字面量,分别表示 100 毫秒和 5 秒。