<chrono> 是 C++11 标准中引入的一个头文件,提供了对时间和时间间隔的精确操作支持。它扩展了 C++ 标准库中对时间的处理,不仅支持高精度的计时和延时,还提供了丰富的时间单位和持续时间类型,能够使开发者更方便地进行时间计算和操作。

目录

  1. <chrono> 头文件简介
  2. 时间类型和单位
  3. 获取当前时间
  4. 时间计算
  5. 定时器与延时操作
  6. 时间格式化与输出
  7. 常见问题和调试
  8. 结论

1. <chrono> 头文件简介

<chrono> 提供了一些类和函数,用于表示时间点、时间间隔以及相关的操作。它提供了比传统的 C++ 时间库(如 <ctime>)更精确的时间表示和计算方式,能够处理多种时间单位,并支持时钟同步。

在 C++ 中,<chrono> 的核心组件包括:

  • 时钟(Clock):用于获取时间点。
  • 持续时间(Duration):表示时间间隔。
  • 时间点(Time Point):表示某一时刻。

你需要通过包含 <chrono> 头文件来使用这些功能:

#include <chrono>


2. 时间类型和单位

2.1 时钟类型

<chrono> 提供了几种不同的时钟类型,常用的有:

  • std::chrono::system_clock:表示系统时间(通常是当前时间),可以转换为 std::time_t 类型。
  • std::chrono::steady_clock:用于测量时间间隔,不受系统时间改变的影响,适合用作计时器。
  • std::chrono::high_resolution_clock:通常提供比 steady_clock 更高的精度,用于高精度计时。

示例:

#include <iostream>
#include <chrono>

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

    system_clock::time_point now = system_clock::now();
    auto duration_since_epoch = now.time_since_epoch();
    std::cout << "Time since epoch: " << duration_cast<seconds>(duration_since_epoch).count() << " seconds" << std::endl;

    steady_clock::time_point start = steady_clock::now();
    // some operation...
    steady_clock::time_point end = steady_clock::now();

    auto duration = duration_cast<milliseconds>(end - start);
    std::cout << "Operation took: " << duration.count() << " milliseconds" << std::endl;

    return 0;
}

2.2 持续时间类型

std::chrono::duration 是用来表示时间间隔的模板类。它有两个主要参数:

  • Rep:表示时间间隔的数值类型(通常为整数或浮动点类型)。
  • Period:表示时间间隔的单位,比如秒、毫秒、微秒等。

常见的时间单位包括:

  • std::chrono::seconds
  • std::chrono::milliseconds
  • std::chrono::microseconds
  • std::chrono::nanoseconds
  • std::chrono::minutes
  • std::chrono::hours

示例:

#include <iostream>
#include <chrono>

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

    seconds sec(5);  // 表示 5 秒
    milliseconds ms = duration_cast<milliseconds>(sec);  // 转换为毫秒
    std::cout << sec.count() << " seconds = " << ms.count() << " milliseconds" << std::endl;

    return 0;
}


3. 获取当前时间

使用 std::chrono 中的时钟,可以获取当前的时间点。常用的时钟类型包括 system_clocksteady_clock

3.1 获取当前时间点

#include <iostream>
#include <chrono>

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

    auto now = system_clock::now();
    std::cout << "Current time point: " << now.time_since_epoch().count() << std::endl;

    return 0;
}

输出:

Current time point: 1620433876576097600


4. 时间计算

通过 std::chrono::duration,可以执行时间的加减、转换等操作。

4.1 加法与减法

#include <iostream>
#include <chrono>

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

    seconds sec1(10);
    seconds sec2(5);
    auto sum = sec1 + sec2;
    auto diff = sec1 - sec2;

    std::cout << "Sum of seconds: " << sum.count() << " seconds" << std::endl;
    std::cout << "Difference of seconds: " << diff.count() << " seconds" << std::endl;

    return 0;
}

输出:

Sum of seconds: 15 seconds
Difference of seconds: 5 seconds

4.2 时间转换

通过 std::chrono::duration_cast 可以在不同时间单位之间进行转换。

#include <iostream>
#include <chrono>

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

    milliseconds ms(1500);  // 1500 milliseconds
    seconds sec = duration_cast<seconds>(ms);  // 转换为秒
    std::cout << "1500 milliseconds = " << sec.count() << " seconds" << std::endl;

    return 0;
}

输出:

1500 milliseconds = 1 seconds


5. 定时器与延时操作

<chrono> 提供了高精度的计时功能,可以用于创建延时操作或定时器。

5.1 延时操作

使用 std::this_thread::sleep_forstd::this_thread::sleep_until 可以让程序暂停执行指定的时间间隔。

#include <iostream>
#include <chrono>
#include <thread>

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

    std::cout << "Sleeping for 2 seconds..." << std::endl;
    std::this_thread::sleep_for(seconds(2));  // 延时 2 秒
    std::cout << "Awake!" << std::endl;

    return 0;
}

5.2 定时器

#include <iostream>
#include <chrono>
#include <thread>

void timer_function() {
    std::cout << "Timer expired!" << std::endl;
}

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

    std::cout << "Timer started, will expire in 3 seconds..." << std::endl;
    std::this_thread::sleep_for(seconds(3));  // 延时 3 秒
    timer_function();  // 调用定时器函数

    return 0;
}


6. 时间格式化与输出

C++ 标准库的 <chrono> 并没有内建直接支持时间格式化的功能。但可以通过将 std::chrono 时间点转换为 std::time_t,再使用 C 标准库的 std::strftime 函数来进行格式化。

6.1 格式化时间输出

#include <iostream>
#include <chrono>
#include <ctime>

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

    auto now = system_clock::now();
    std::time_t now_time_t = system_clock::to_time_t(now);
    std::tm* now_tm = std::localtime(&now_time_t);

    char buffer[100];
    std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", now_tm);
    std::cout << "Formatted time: " << buffer << std::endl;

    return 0;
}

输出:

Formatted time: 2021-04-04 13:30:45


7. 常见问题和调试

  • 时区问题std::chrono 获取的时间通常是 UTC 时间。如果需要转换为本地时间,需要使用 std::localtime
  • 高精度计时:对于需要高精度计时的应用,建议使用 std::chrono::high_resolution_clock,它提供更高的计时精度。

8. 结论

<chrono> 提供了对时间点、时间间隔以及高精度计时的全面支持,具有很高的灵活性和精确性。通过使用 std::chrono::system_clockstd::chrono::steady_clockstd::chrono::high_resolution_clock 等时钟类型,可以在 C++ 程序中进行精确的时间操作和计算。

推荐阅读: