C++风格获取时间API

包含的头文件

#include <chrono>

命名空间

std::chrono

涉及类

chrono 库定义三种主要类型以及工具函数和常用 typedef 。

  • 时钟
  • 时长
  • 时间点

时钟

时钟由起点(或纪元)及计次频率组成。例如,时钟可以拥有 1970 年 1 月 1 日的纪元,和每一秒的计次。 C++ 定义数种时钟类型:

std::chrono::system_clock

std::chrono::steady_clock (不做具体说明,可参照上述system_clock)

三个静态成员函数

1. now

2. to_time_t

3. from_time_t

(1) now()函数

可用于获取当前时间戳

static std::chrono::time_point<std::chrono::system_clock> now() noexcept;

(C++11 起)

返回表示当前时间的时间点。
参照头文件中定义可知该函数声明展开应该是:

static std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> now() noexcept(); 

struct system_clock
    {
      typedef chrono::nanoseconds     				duration;
      typedef duration::rep    					rep;
      typedef duration::period 					period;
      typedef chrono::time_point<system_clock, duration> 	time_point;

      static_assert(system_clock::duration::min()
		    < system_clock::duration::zero(),
		    "a clock's minimum duration cannot be less than its epoch");

      static constexpr bool is_steady = false;

      static time_point
      now() noexcept;

      // Map to C API
      static std::time_t
      to_time_t(const time_point& __t) noexcept
      {
	return std::time_t(duration_cast<chrono::seconds>
			   (__t.time_since_epoch()).count());
      }

      static time_point
      from_time_t(std::time_t __t) noexcept
      {
	typedef chrono::time_point<system_clock, seconds>	__from;
	return time_point_cast<system_clock::duration>
	       (__from(chrono::seconds(__t)));
      }
    };

使用示例:

#include <chrono>
using namespace std::chrono;
system_clock::time_point tp = system_clock::now();

(2) to_time_t() 函数

将时间戳转换成整型数

static std::time_t to_time_t( const time_point& t ) noexcept;

(C++11 起)

转换 t 为 std::time_t 类型。

若 std::time_t 拥有较低精度,则是舍入还是截断值是实现定义的。

std::time_t是C风格的表示,可以理解为整数类型值,详细说明见下:

定义于头文件 <ctime>

typedef /* 未说明 */ time_t;

足以表示时间的算术类型。

虽然标准中没有给出定义,但是该类型几乎总是整数类型,表示自 1970 年 1 月 1 日 00:00 UTC 以来所经过的秒数(不计闰秒),对应 POSIX 时间

(3) from_time_t() 函数

将整型数转换成时间戳time_point

static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept;

(C++11 起)

用二个类型间的较低精度,转换 t 为时间点类型。

time_point 拥有较低精度,则舍入还是截断值是实现定义的。

时间点

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

std::chrono::time_point

成员函数

(1)time_since_epoch

  (2)   time_point_cast

类定义

template<

    class Clock,
    class Duration = typename Clock::duration

> class time_point;

构造该对象时候需要传入两个参数:

(1)Clock

  (2)   Duration

可以参考std::chrono::system_clock::time_point定义

typedef chrono::time_point<system_clock, duration> 	time_point;
    typedef chrono::nanoseconds     				duration;
    typedef duration<int64_t, nano> 	    nanoseconds;
    typedef ratio<1,                1000000000> nano;

Clock -> system_clock
duration -> chrono::nanoseconds //纳秒
            chrono::nanoseconds -> -> std::chrono::duration<int64_t, nano> 
            nano -> typedef ratio<1,                1000000000> nano;
            

time_since_epoch 函数

duration time_since_epoch() const;

(C++11 起)
(C++14 前)

constexpr duration time_since_epoch() const;

(C++14 起)

返回表示 *this 与 clock 的纪元间的时间量的 duration 。

time_point_cast() 函数

template <class ToDuration, class Clock, class Duration>

time_point<Clock, ToDuration> time_point_cast(

                                 const time_point<Clock, Duration> &t);
(C++11 起)
(C++14 前)
template <class ToDuration, class Clock, class Duration>

constexpr time_point<Clock, ToDuration> time_point_cast(

                                 const time_point<Clock, Duration> &t);
(C++14 起)

将 std::chrono::time_point 从一个 duration 到另一个。

上述两个函数结合示例:

auto p1 = std::chrono::system_clock::now();
std::cout << "hours since epoch: "
              << std::chrono::duration_cast<std::chrono::hours>(
                   p1.time_since_epoch()).count() 

时长

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

std::chrono::duration

成员函数:

(1) count

(2) duration_cast

辅助类型:

std::chrono::nanosecondsduration</*至少 64 位的有符号整数类型*/, std::nano>
std::chrono::microsecondsduration</*至少 55 位的有符号整数类型*/, std::micro>
std::chrono::millisecondsduration</*至少 45 位的有符号整数类型*/, std::milli>
std::chrono::secondsduration</*至少 35 位的有符号整数类型*/>
std::chrono::minutesduration</*至少 29 位的有符号整数类型*/, std::ratio<60>>
std::chrono::hoursduration</*至少 23 位的有符号整数类型*/, std::ratio<3600>>

类定义

template<

    class Rep,
    class Period = std::ratio<1>

> class duration;
(C++11 起)

类模板 std::chrono::duration 表示时间间隔。

它由 Rep 类型的计次数和计次周期组成,其中计次周期是一个编译期有理数常量,表示从一个计次到下一个的秒数。

存储于 duration 的数据仅有 Rep 类型的计次数。若 Rep 是浮点数,则 duration 能表示小数的计次数。 Period 被包含为时长类型的一部分,且只在不同时长间转换时使用。

count() 函数

constexpr rep count() const;

返回此 duration 的计次数。

示例:

#include <chrono>
#include <iostream>
int main()
{
    std::chrono::milliseconds ms{3}; // 3 毫秒
    // 从 3 毫秒构造 6000 微秒
    std::chrono::microseconds us = 2*ms;
    // 使用分数计次的 30Hz 时钟
    std::chrono::duration<double, std::ratio<1, 30>> hz30(3.5);
 
    std::cout <<  "3 ms duration has " << ms.count() << " ticks\n"
              <<  "6000 us duration has " << us.count() << " ticks\n"
              <<  "3.5 30Hz duration has " << hz30.count() << " ticks\n";   

duration_cast() 函数

template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep,Period>& d);

(C++11 起)

转换 std::chrono::duration 为不同类型 ToDuration 的时长。

不使用隐式转换。可能的情况下避免乘法和除法,若在编译时已知一或多个参数为 1 。以最宽的可用类型进行计算,而如同用 static_cast 到结果类型的转换,只在完成时进行。

示例:

#include <iostream>
#include <chrono>
#include <ratio>
#include <thread>
 
void f()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
 
int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    f();
    auto t2 = std::chrono::high_resolution_clock::now();
 
    // 整数时长:要求 duration_cast
    auto int_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
 
    // 小数时长:不要求 duration_cast
    std::chrono::duration<double, std::milli> fp_ms = t2 - t1;
 
    std::cout << "f() took " << fp_ms.count() << " ms, "
              << "or " << int_ms.count() << " whole milliseconds\n";
}

总结:目前使用到的C++风格的时间相关函数,只能拿到时间戳,实现的功能很少,实用性较低,且封装成static函数,偏C的风格更多,不是很好~。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值