跳转至

时间日期库

1 c风格库

1.1 类型tmtime_tclock_ttimespec

  • 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]
};

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