C/C++实现获取系统时间的示例代码
iBlackAngel 人气:0概述
C 标准库提供了 time() 函数与 localtime() 函数可以获取到当前系统的日历时间,但 time() 函数精度只能到秒级,如果需要更高精度的系统时间需要使用 gettimeofday() 函数,精度达到微秒级。
#include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz);
tv 参数是一个 struct timeval 结构体(同样是在 <sys/time.h> 头文件中定义):
struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ };
时区结构体 struct timezone 的使用已过时,tz 参数通常应指定为 NULL。
函数 localtime() 把 timep 指向的日历时间转换为表示本地时间的细分时间。
#include <time.h> struct tm *localtime(const time_t *timep);
localtime() 返回一个指向 struct tm 对象的指针,它保存了一个日历时间的各组成部分,日历时间也被称为细分时间(Broken-down time)。该结构体定义在 <time.h> 头文件中:
struct tm { int tm_sec; /* Seconds (0-60) */ int tm_min; /* Minutes (0-59) */ int tm_hour; /* Hours (0-23) */ int tm_mday; /* Day of the month (1-31) */ int tm_mon; /* Month (0-11) */ int tm_year; /* Year - 1900 */ int tm_wday; /* Day of the week (0-6, Sunday = 0) */ int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */ int tm_isdst; /* Daylight saving time */ };
tm 结构体的成员:
tm_sec —— 分钟后的秒数,通常在 59 秒的范围内,但最多可以达到 60 秒,以允许闰秒。
tm_min —— 小时后的分钟数,范围为 0 到 59。
tm_hour —— 午夜过后的小时数,范围为 0 到 23。
tm_mday —— 一个月的某一天,范围为 1 到 31。
tm_mon —— 自 1 月以来的月份数,范围为 0 到 11(显示月份的时候需要加 1)
tm_year —— 自 1900 年以来的年数(显示年份的时候需要加上 1900)
tm_wday —— 自周日(星期日)以来的天数,范围为 0 到 6。
tm_yday —— 自 1 月 1 日以来的天数,范围为 0 到 365。
tm_isdst —— 指示夏时制在所述时间是否有效的标志。如果夏令时有效,则该值为正值;如果夏令时无效,则为零;如果信息不可用,则为负值。
示例
#include <stdio.h> // included for 'printf()' #include <sys/time.h> // included for 'gettimeofday()' #include <time.h> // included for 'localtime()' int main(int argc, char const *argv[]) { struct timeval tv; gettimeofday(&tv, NULL); time_t sec = tv.tv_sec; suseconds_t usec = tv.tv_usec; struct tm *lt = localtime(&sec); printf("%d-%02d-%02d %02d:%02d:%02d.%03d\n", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int)(usec / 1000)); return 0; }
使用 gettimeofday 获取到保存在 timeval 结构体的时间之后,通过 localtime 函数将 tv_sec 转换成 struct tm 结构体,在关键的 tm_year, tm_mon 进行特殊处理计算出当前到秒的日历时间,然后通过将 tv_usec 微秒数除以 1000 得到毫秒数。
在命令行使用 gcc 编译:
gcc -o main main.c
结果为带毫秒数的当前日历时间:
$ ./main
2022-12-15 11:03:56.847
易用性封装
如果需要直接在代码中获取当前带毫秒数的日历时间,可以参考以下封装接口:
使用 C++11 标准的 thread_local 创建一个线程安全的全局变量,然后将运算结果存储在全局变量中,最后返回对象的指针,这样既能保证调用函数的易用性,同时也能兼顾运算性能,这种写法可以非常简单地应用到大部分应用中:
thread_local char __timebuf[64] = {0x00}; const char *curtime() { struct timeval tv; gettimeofday(&tv, NULL); struct tm *lt = localtime(&tv.tv_sec); snprintf(__timebuf, sizeof(__timebuf) - 1, "%d-%02d-%02d %02d:%02d:%02d.%03d", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int)(tv.tv_usec / 1000)); return __timebuf; }
加载全部内容