跳转至

时间日期库

1 c 风格库

1.1 类型 tmtime_tclock_ttimespectimeval

  • tm 是一个用于保存年、月、日、时、分、秒这些独立数据的结构。
struct tm
{
    int tm_sec;   // seconds after the minute - [0, 60] including leap second
    int tm_min;   // minutes after the hour - [0, 59]
    int tm_hour;  // hours since midnight - [0, 23]
    int tm_mday;  // day of the month - [1, 31]
    int tm_mon;   // months since January - [0, 11]
    int tm_year;  // years since 1900
    int tm_wday;  // days since Sunday - [0, 6]
    int tm_yday;  // days since January 1 - [0, 365]
    int tm_isdst; // daylight savings time flag
};
  • time_t 是一个足以表示时间(UNIX 时间,或称 POSIX 时间)的算术类型,从纪元时间(UTC1970 年 1 月 1 日 0 时 0 分 0 秒)算起缩进过的时间,单位 s
typedef long long time_t;
  • clock_t 是一个足以表示实现定义范围和精度的进程运行时间的算术类型
typedef long clock_t;
  • timespec 是一个保有时长的结构体,拆分成秒和纳秒

struct timespec
{
    time_t tv_sec;  // Seconds - >= 0
    long   tv_nsec; // Nanoseconds - [0, 999999999]
};
- timeval :由秒和微妙组成,可以由 gettimeofday 得到
struct timeval
{
    __time_t tv_sec;        /* Seconds.  */
    __suseconds_t tv_usec;  /* Microseconds.  */
};

1.2 时间操作函数

1.2.1 difftime

  • 语法形式:double difftime( std::time_t time_end, std::time_t time_beg );
  • 功能:计算 2 个时间差,结果是 double 类型,以秒为单位
#include<ctime>
//window特有库
#include<Windows.h>
int main()
{
    std::time_t t_start = std::time(NULL);
    Sleep(2000);//休眠2秒
    printf("时间差%lfs",std::difftime(std::time(NULL), t_start));
}
//输出结果
//时间差2.000000s

1.2.2 time

  • 语法形式:std::time_t time( std::time_t* arg );
  • 功能:计算当前日历时间,保存为 std::time_t 格式,将结果存入 arg 所指内存,并返回结果
  • 示例
#include<ctime>
int main()
{
    std::time_t t_start = std::time(NULL);
    printf("本地格式化当前时间:%s",std::asctime(std::localtime(&t_start)));
}

1.2.3 clock

  • 语法形式:std::clock_t clock();
  • 功能:返回进程从关联到程序执行的实现定义时期开始,所用的粗略处理器时间,单位 ms
  • 示例
#include <iostream>
#include <iomanip>
#include <chrono>
#include <ctime>
#include <thread>

// 函数 f() 做一些耗时工作
void f()
{
    volatile double d = 0;
    for(int n=0; n<10000; ++n)
       for(int m=0; m<10000; ++m)
           d += d*n*m;
}

int main()
{
    std::clock_t c_start = std::clock();
    auto t_start = std::chrono::high_resolution_clock::now();
    std::thread t1(f);
    std::thread t2(f); // 在二个线程上调用 f()
    t1.join();
    t2.join();
    std::clock_t c_end = std::clock();
    auto t_end = std::chrono::high_resolution_clock::now();

    std::cout << std::fixed << std::setprecision(2) << "CPU time used: "
              << 1000.0 * (c_end-c_start) / CLOCKS_PER_SEC << " ms\n"
              << "Wall clock time passed: "
              << std::chrono::duration<double, std::milli>(t_end-t_start).count()
              << " ms\n";
}
//输出可能结果
//CPU time used: 1590.00 ms
//Wall clock time passed: 808.23 ms

1.3 格式转换函数

  • localtimegmtime 比较
  • 相同点:将 time_t 格式时间转换为 tm 格式时间
  • 不同点:根据不同时区来转换
  • asctimectime 比较
  • 相同点: 转换成 Www Mmm dd hh:mm:ss yyyy\n 格式的 c 字符串表示
  • 不同点:asctime 入参是 tm 指针,ctime 入参是 time_t 指针
  • strftimewcsftime 比较
  • 相同点:按入参的 format 指定格式来格式化时间
  • 不同点:strftime 转换窄字节字符串,wcsftime 转换宽字节字符串

1.3.1 localtime

  • 语法形式:std::tm* localtime( const std::time_t *time );
  • 功能:转换 time_t 格式时间为以本地时间表示的 tm 格式时间
  • 示例
#include<ctime>
int main()
{
    std::time_t t_start = std::time(NULL);
    std::tm* t=std::localtime(&t_start);
}

1.3.2 gmtime

  • 语法形式:std::tm* gmtime( const std::time_t* time );
  • 功能:转换 time_t 格式时间为以 UTC 时间表示的 tm 格式时间
  • 示例
#include<ctime>
int main()
{
    std::time_t t_start = std::time(NULL);
    std::tm* t=std::gmtime(&t_start);
}

1.3.3 asctime

  • 语法形式:char* asctime( const std::tm* time_ptr );
  • 功能:转换 tm 格式时间为字符串表示,占 25 字符,格式为 Www Mmm dd hh:mm:ss yyyy\n
  • 示例
#include<ctime>
#include <ctime>
#include <iostream>

int main()
{
    std::time_t result = std::time(NULL);
    std::cout << std::asctime(std::localtime(&result));
}
//输出可能结果
//Wed Dec 23 09:25:25 2020

1.3.4 ctime

  • 语法形式:char* ctime( const std::time_t* time );
  • 功能:先转换 time_t 格式时间,再转换 tm 格式时间为字符串表示,格式为 Www Mmm dd hh:mm:ss yyyy\n
  • 示例
#include <ctime>
#include <iostream>

int main()
{
    std::time_t result = std::time(NULL);
    std::cout << std::ctime(std::localtime(&result));
}
//输出可能结果
//Wed Dec 23 09:39:11 2020

1.3.5 strftime

  • 语法形式:std::size_t strftime( char* str, std::size_t count, const char* format, const std::tm* time );
  • 功能:按照格式字符串 format ,转换来自给定的日历时间 time 的日期和时间信息,为空终止多字节字符串 str 。最多写入 count 字节。
  • 示例
#include <ctime>
#include <iostream>
#include <locale>

int main()
{
    std::locale::global(std::locale("zh_CN"));
    std::time_t t = std::time(NULL);
    char mbstr[100];
    if (std::strftime(mbstr, sizeof(mbstr), "%A %c", std::localtime(&t))) {
        std::cout << mbstr << '\n';
    }
}
//输出可能结果
//星期三 2020/12/23 9:48:22

1.3.6 wcsftime

  • 语法形式:std::size_t wcsftime( wchar_t* str, std::size_t count, const wchar_t* format, const std::tm* time );
  • strtimewcsftime 按格式转成宽字符表示字符串

1.3.7 mktime

  • 语法形式:std::time_t mktime( std::tm* time );
  • 功能:转换 tm 格式时间为 time_t 格式时间
  • 示例
#include <ctime>
#include <iostream>
int main()
{
    std::time_t tt = std::time(NULL);
    std::cout << "std::time结果:" << tt << std::endl;
    std::tm* t = std::localtime(&tt);
    std::time_t tt1=std::mktime(t);
    std::cout << "std::mktime结果:" << tt1 << std::endl;
}
//输出可能结果
//std::time结果:1608689575
//std::mktime结果:1608689575

2 时间戳转格式化时间

  • 示例
#include<string>
#include<stdio.h>
#include<time.h>
using namespace std;
string get_current_time()
{
    time_t cur_time;  
    struct tm *p;  
    time(&cur_time);
    p=localtime(&cur_time);  
    char s[100];  
    strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", p);  
    return string(s);
}

int main()
{
    printf("date is %s\n",get_current_time().c_str());
}

3 计时器函数

3.1 标准库

  • time() 精度 s
  • clock() 精度 ms
using namespace std;
void run()
{
    for (int num=999999,i=0;i<num;i++)
    {
        i* i;
    }
}
int main()
{
    //clock 单位 ms
    clock_t ct_start = clock();
    run();
    clock_t ct_end = clock();
    printf("clock time:%fms\n", double(ct_end - ct_start));
    //time 单位s
    time_t tm_start= time(NULL);
    run();
    time_t tm_end = time(NULL);
    printf("time time:%fs\n", double(tm_start - tm_end));
}

3.2 windows 平台

  • QueryPerformanceCounter 精度<0.1ms
#include <Windows.h>
int main()
{
    LARGE_INTEGER t1,t2,tc;
    //查询性能计数器的频率n/s
    QueryPerformanceFrequency(&tc);
    //查询性能计数器当前值
    QueryPerformanceCounter(&t1);
      Sleep(1500);
    QueryPerformanceCounter(&t2);
    printf("Use Time:%lfs\n",(t2.QuadPart - t1.QuadPart)*1.0/tc.QuadPart);
}

3.3 linux 平台

  • gettimeofday 精度微秒μs
#include<stdio.h>
#include<sys/time.h>
#include<unistd.h>
int main()
{
    timeval start,end;
    unsigned  long diff;
    gettimeofday(&start,NULL);
    printf("start tv_sec:%d\n",start.tv_sec);
    printf("start tv_usec:%d\n",start.tv_usec);
    gettimeofday(&end,NULL);
    printf("end tv_sec:%d\n",end.tv_sec);
    printf("end tv_usec:%d\n",end.tv_usec);
    diff = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;
    printf("thedifference is %ldμs\n",diff);
}
//可能的输出
//start tv_sec:1609380544
//start tv_usec:665505
//end tv_sec:1609380544
//end tv_usec:665522
//thedifference is 17μs