时间操作chrono库

时间操作chrono库

C++中chrono库是一个用于处理时间的库。它提供了一种方便、安全且高精度的方式来进行时间的测量和持续时间操作。

时间长度(Durations)

chrono库中,时间长度是通过duration类模板表示的,它表示两个事件之间的时间差。这个模板包含两个参数:一个是代表时间的数值类型(Rep),另一个是一个比率类型(Period),表示每个时间单位代表的秒数的分数。

template<class Rep, class Period = std::ratio<1, 1>>
class duration;

这个模板类在内部使用Rep类型的变量来存储时间长度,并使用Period来解释这个值代表的时间单位。

标准时间单位

为了方便,chrono已经定义了一些常见的duration类型,用于表示常用的时间单位,如小时、分钟、秒等。这些预定义的类型是基于chrono::duration的特化。

using hours           = duration<long long, std::ratio<3600>>;    // 小时
using minutes         = duration<long long, std::ratio<60>>;      // 分钟
using seconds         = duration<long long>;                      // 秒
using milliseconds    = duration<long long, std::milli>;          // 毫秒
using microseconds    = duration<long long, std::micro>;          // 微秒
using nanoseconds     = duration<long long, std::nano>;           // 纳秒
duration的操作

duration对象可以进行常规的算术操作,如加法、减法和比较。这让时间计算变得直观且容易理解。

  • 算术运算:可以直接使用标准的算术运算符(如+, -)来对duration对象进行计算。
  • 比较:duration对象可以使用比较运算符(如==, !=, <, >)进行比较。
  • 获取数值:使用count()方法可以获取存储在duration对象中的原始数值(即时间长度)。

下面是一个完整示例:

#include <iostream>
#include <chrono>  // 引入时间库

using namespace std;

int main() {
    // 创建不同的时间单位
    chrono::hours t1(1);  // 1小时
    chrono::minutes t2(60);  // 60分钟
    chrono::seconds t3(60 * 60);  // 3600秒
    chrono::milliseconds t4(60 * 60 * 1000);  // 3600000毫秒

    // 比较不同时间单位间的等价性
    if (t1 == t2) cout << "1 hour is equal to 60 minutes\n";
    if (t1 == t3) cout << "1 hour is equal to 3600 seconds\n";
    if (t1 == t4) cout << "1 hour is equal to 3600000 milliseconds\n";

    // 打印各时间单位的原始值
    cout << "1 hour in hours: " << t1.count() << '\n';
    cout << "60 minutes in minutes: " << t2.count() << '\n';
    cout << "3600 seconds in seconds: " << t3.count() << '\n';
    cout << "3600000 milliseconds in milliseconds: " << t4.count() << '\n';

    // 创建更多的时间单位
    chrono::seconds t7(1);  // 1秒
    chrono::milliseconds t8(1000);  // 1000毫秒
    chrono::microseconds t9(1000 * 1000);  // 1000000微秒
    chrono::nanoseconds t10(1000 * 1000 * 1000);  // 1000000000纳秒

    // 比较新创建的时间单位间的等价性
    if (t7 == t8) cout << "1 second is equal to 1000 milliseconds\n";
    if (t7 == t9) cout << "1 second is equal to 1000000 microseconds\n";
    if (t7 == t10) cout << "1 second is equal to 1000000000 nanoseconds\n";

    // 打印更多时间单位的原始值
    cout << "1 second in seconds: " << t7.count() << '\n';
    cout << "1000 milliseconds in milliseconds: " << t8.count() << '\n';
    cout << "1000000 microseconds in microseconds: " << t9.count() << '\n';
    cout << "1000000000 nanoseconds in nanoseconds: " << t10.count() << '\n';

    return 0;
}

系统时间

C++中的std::chrono::system_clock类是处理系统相关时间的重要工具。它是chrono库的一部分,主要用于表示和操作系统时间。system_clock提供了几个功能,包括获取当前时间、将时间点转换为传统的时间表示(如time_t),以及**从传统时间类型创建时间点。**下面是关于system_clock各个方面的详细解释:

  1. 获取当前时间点(系统时间)

std::chrono::system_clock::now()是一个静态成员函数,返回一个代表当前系统时间的time_point对象。这是你获取系统当前时间的起点。

auto now = chrono::system_clock::now();

在这里,now是一个time_point类型的对象,代表了调用now()时的时间点。

  1. 将时间点time_point类型转换为std::time_t类型

    C++中的time_t通常用来存储自纪元(1970年1月1日)以来的秒数。它是C和C++中传统的时间处理方式。

auto t_now = chrono::system_clock::to_time_t(now);

这里,t_now是一个time_t类型的对象,包含了与time_point对象now相对应的UTC时间(协调世界时)。

  1. std::time_t类型转换为时间点time_point类型

    to_time_t相反的是,from_time_t函数可以让你从一个time_t对象创建一个time_point对象,这在你需要与使用time_t的老旧代码交互时非常有用。

std::time_t tt = std::time(nullptr); // 获取当前的系统时间
auto timepoint = std::chrono::system_clock::from_time_t(tt);
  1. 处理本地时间
    你可以将time_t类型的时间转换为结构化的时间,这通常更方便人们阅读和处理。C++中使用std::tm结构体来表示结构化时间。
auto tm_now = std::localtime(&t_now);

​ 在这里,tm_now是一个指向tm结构体的指针,它包含了本地时间(考虑了时区的时间)。请注意,localtime是不安全的,因为它在内部使用了静态存储区域,所以在多线程环境下需要谨慎使用。

  1. 格式化时间输出:
    当你想以一种可读的方式打印或显示时间时,可以使用C++中的std::put_time来格式化tm结构体的输出。
cout << std::put_time(tm_now, "%Y-%m-%d %H:%M:%S") << endl;

这行代码会按照"年-月-日 时:分:秒"的格式输出时间。你可以使用不同的格式化字符串来改变输出的格式。

cout << std::put_time(tm_now, "%Y-%m-%d %H:%M:%S") << std::endl;
cout << std::put_time(tm_now, "%Y-%m-%d") << std::endl;
cout << std::put_time(tm_now, "%H:%M:%S") << std::endl;
cout << std::put_time(tm_now, "%Y%m%d%H%M%S") << std::endl;
  1. 使用字符串流格式化时间:

    stringstream ss;
    ss << std::put_time(tm_now, "%Y-%m-%d %H:%M:%S");
    string timestr = ss.str();
    cout << timestr << endl;
    

    在这里,我们使用了一个std::stringstream来创建一个格式化的时间字符串。stringstream可以像使用流操作符(如<<)操作std::cout那样来操作字符串。这使得字符串的创建和操作更加灵活和强大。

下面是一个完整示例:

#include <iostream>     // 包含输入/输出流的头文件
#include <chrono>       // 包含chrono库的头文件,用于处理时间
#include <ctime>        // 包含处理日期和时间的函数
#include <iomanip>      // 包含格式化输出的函数,如put_time
#include <sstream>      // 包含字符串流

using namespace std;    // 使用std命名空间

int main() {
    // 步骤1: 获取当前系统时间
    auto now = chrono::system_clock::now();

    // 步骤2: 将时间点转换为time_t类型
    auto t_now = chrono::system_clock::to_time_t(now);

    // 步骤3: 对时间进行操作(如果需要的话)
    // t_now = t_now + 24*60*60;  // 例如,增加一天的秒数

    // 步骤4: 将time_t转换为本地时间
    auto tm_now = localtime(&t_now); // 转换为本地时间

    // 步骤5: 格式化时间的输出
    cout << "Current time in various formats:" << endl;
    cout << put_time(tm_now, "%Y-%m-%d %H:%M:%S") << endl; // 年-月-日 时:分:秒
    cout << put_time(tm_now, "%Y-%m-%d") << endl; // 年-月-日
    cout << put_time(tm_now, "%H:%M:%S") << endl; // 时:分:秒

    // 步骤6: 使用字符串流格式化时间
    stringstream ss;
    ss << put_time(tm_now, "%Y-%m-%d %H:%M:%S"); // 向流中插入格式化时间
    string timestr = ss.str(); // 从流中获取字符串

    cout << "Time from stringstream: " << timestr << endl; // 输出从字符串流获取的时间

    return 0; // 主函数返回0,表示程序成功结束
}

计时器

在许多情况下,开发人员需要测量特定操作的执行时间,例如性能测试、基准测试或简单的时间追踪。C++中的chrono库包含steady_clock类相当于秒表,操作系统只要启动就会进行时间的累加,常用于耗时的统计(精确到纳秒)。

以下是如何使用 steady_clock 创建一个计时器的步骤概述:

#include <iostream>
#include <chrono>
using namespace std;

int main()
{
    // 静态成员函数chrono::steady_clock::now()获取开始的时间点。
    auto start = chrono::steady_clock::now();

    // 执行一些代码,让它消耗一些时间。
    cout << "计时开始 ...... \n";
    for (int ii = 0; ii < 1000000; ii++) {
        // cout << "我是一只傻傻鸟。\n";
    }
    cout << "计时完成 ...... \n";

    // 静态成员函数chrono::steady_clock::now()获取结束的时间点。
    auto end = chrono::steady_clock::now();

    // 计算消耗的时间,单位是纳秒。
    auto dt = end - start;
    cout << "耗时: " << dt.count() << "纳秒("<<(double)dt.count()/(1000*1000*1000)<<"秒)";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tian Meng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值