C 标准库提供了 time()
函数与 localtime()
函数可以获取到当前系统的日历时间,但 time()
函数精度只能到秒级,如果需要更高精度的系统时间需要使用 gettimeofday()
函数,精度达到微秒级。
#include
int gettimeofday(struct timeval *tv, struct timezone *tz);
tv
参数是一个 struct timeval
结构体(同样是在
头文件中定义):
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
时区结构体 struct timezone
的使用已过时,tz
参数通常应指定为 NULL。
函数 localtime()
把 timep
指向的日历时间转换为表示本地时间的细分时间。
#include
struct tm *localtime(const time_t *timep);
localtime()
返回一个指向 struct tm
对象的指针,它保存了一个日历时间的各组成部分,日历时间也被称为细分时间(Broken-down time)。该结构体定义在
头文件中:
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
结构体的成员:
#include // included for 'printf()'
#include // included for 'gettimeofday()'
#include // 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;
}
△ \triangle △ Linux C/C++ 单实例进程设计