1、clock_gettime
#include /** * @brief 根据系统时钟的类型,获取当前时间 * * Detailed function description * * @param[in] __clock_id: 系统时钟的类型。常用取值: - CLOCK_REALTIME: 从1970年1月1日到目前的时间 - CLOCK_MONOTONIC: 系统启动时间 - CLOCK_PROCESS_CPUTIME_ID: 本进程运行时间 - CLOCK_THREAD_CPUTIME_ID: 本线程运行的时间 * @param[out] __tp: 存放当前的时间。 * * @return 成功则返回0,失败则返回-1 */ int clock_gettime (clockid_t __clock_id, struct timespec *__tp) ;
timespec结构体:
struct timespec { __time_t tv_sec; /* Seconds. 秒 */ __syscall_slong_t tv_nsec; /* Nanoseconds. 纳秒*/ };
例子:
#include #include #include long long get_clock_sys_time_ns (void ) { struct timespec tp ; long long time_ns = 0 ; clock_gettime(CLOCK_MONOTONIC, &tp); time_ns = (long long )tp.tv_sec * 1000000000 + tp.tv_nsec; return time_ns; }int main (void ) { struct timespec tp ; ///< 获取从1970年1月1日到目前的时间 memset (&tp, 0 , sizeof (struct timespec)); clock_gettime(CLOCK_REALTIME, &tp); printf ("clock_id = CLOCK_REALTIME, sec = %ld, nsec = %ld\n" , tp.tv_sec, tp.tv_nsec); ///< 获取系统启动时间 memset (&tp, 0 , sizeof (struct timespec)); clock_gettime(CLOCK_MONOTONIC, &tp); printf ("clock_id = CLOCK_MONOTONIC, sec = %ld, nsec = %ld, sys_time = %lld ns\n" , tp.tv_sec, tp.tv_nsec, get_clock_sys_time_ns()); ///< 获取本进程运行时间 memset (&tp, 0 , sizeof (struct timespec)); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp); printf ("clock_id = CLOCK_PROCESS_CPUTIME_ID, sec = %ld, nsec = %ld\n" , tp.tv_sec, tp.tv_nsec); ///< 获取本线程运行时间 memset (&tp, 0 , sizeof (struct timespec)); clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp); printf ("clock_id = CLOCK_THREAD_CPUTIME_ID, sec = %ld, nsec = %ld\n" , tp.tv_sec, tp.tv_nsec); return 0 ; }
编译、运行:
2、gettimeofday
#include /** * @brief 获取当前时间(从1970年1月1日到目前的时间) * * Detailed function description * * @param[out] tv: 当前UTC时间 * @param[out] tz: 当前时区信息 * * @return 成功则返回0,失败则返回-1 */ int gettimeofday (struct timeval *tv, struct timezone *tz) ;
timeval结构体:
struct timeval { __time_t tv_sec; /* Seconds. 秒*/ __suseconds_t tv_usec; /* Microseconds. 微秒*/ };
timezone结构体:
struct timezone { int tz_minuteswest; /* Minutes west of GMT. 和Greenwich时间差了多少分钟 */ int tz_dsttime; /* Nonzero if DST is ever in effect. 日光节约时间的状态 */ };
例子:
#include #include #include long long get_sys_time_ms (void ) { long long time_ms = 0 ; struct timeval tv ; gettimeofday(&tv, NULL ); time_ms = ((long long )tv.tv_sec*1000000 + tv.tv_usec) / 1000 ; return time_ms; }int main (void ) { ///< 获取系统时间 printf ("sys_time = %lld ms\n" , get_sys_time_ms()); return 0 ; }
编译、运行:
3、time
#include
/** * @brief 获取1970-01-01 00:00:00 +0000至今的秒数(UTC) * * Detailed function description * * @param[out] tloc: 返回的秒存储指针 * * @return 成功则返回秒数,失败则返回-1,错误原因存在errno中。 */ time_t time (time_t *tloc) ;
time_t的类型:
typedef long time_t ;
例子:
#include #include time_t get_utc_time (void ) { return time(NULL ); }int main (int argc, char **argv) { time_t utc_time = get_utc_time(); printf ("utc_time = %ld s\n" , utc_time); return 0 ; }
编译、运行:
4、localtime
#include /** * @brief 将time_t类型的时间转换为struct tm类型的时间 * * Detailed function description * * @param[in] timep: 当前UTC秒数 * * @return 返回当地时间 */ struct tm *localtime (const time_t *timep) ;
tm结构体:
struct tm { int tm_sec; /* Seconds. [0-60] (1 leap second) */ int tm_min; /* Minutes. [0-59] */ int tm_hour; /* Hours. [0-23] */ int tm_mday; /* Day. [1-31] */ int tm_mon; /* Month. [0-11] 注意:0代表1月,以此类推*/ int tm_year; /* Year - 1900. 该值为实际年份减去1900*/ int tm_wday; /* Day of week. [0-6] 注意:0代表星期一,以此类推*/ int tm_yday; /* Days in year.[0-365] 从每年的1月1日开始的天数,其中0代表1月1日,以此类推*/ int tm_isdst; /* DST. [-1/0/1] 夏玲时标识符*/ };
例子:
#include #include time_t get_utc_time (void ) { return time(NULL ); }int main (int argc, char **argv) { time_t utc_time = get_utc_time(); printf ("utc_time = %ld s\n" , utc_time); struct tm *local_tm = localtime (&utc_time ); printf ("local time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n" , local_tm->tm_year + 1900 , local_tm->tm_mon + 1 , local_tm->tm_mday, local_tm->tm_hour, local_tm->tm_min, local_tm->tm_sec); return 0 ; }
编译、运行:
5、localtime_r
#include /** * @brief 将time_t类型的时间转换为struct tm类型的时间 * * Detailed function description * * @param[in] timep: 当前UTC秒数 * @param[out] timep: 当地时间 * * @return 返回当地时间 */ struct tm *localtime_r (const time_t *timep, struct tm *result) ;
localtime不是一个线程安全的函数,关于线程安全的知识点,看阅读往期文章:
如何理解线程安全?
。
对于实时性要求较高的系统,多个线程同时调用localtime,可能会造成数据被覆盖。我们项目中之前是用localtime来获取系统时间、日期。并使用这个数据去做逻辑,数据异常导致了逻辑异常。
后面使用localtime_r来替代,问题解决。
例子:
#include #include time_t get_utc_time (void ) { return time(NULL ); }int main (int argc, char **argv) { time_t utc_time = get_utc_time(); printf ("utc_time = %ld s\n" , utc_time); struct tm result ; struct tm *local_tm = localtime_r (&utc_time , &result ); printf ("local time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n" , local_tm->tm_year + 1900 , local_tm->tm_mon + 1 , local_tm->tm_mday, local_tm->tm_hour, local_tm->tm_min, local_tm->tm_sec); printf ("result time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n" , result.tm_year + 1900 , result.tm_mon + 1 , result.tm_mday, result.tm_hour, result.tm_min, result.tm_sec); return 0 ; }
编译、运行:
6、gmtime
#include /** * @brief 返回tm结构的GMT时间(UTC时间) * * Detailed function description * * @param[in] timep: 当前UTC秒数 * * @return 返回当地时间 */ struct tm *gmtime (const time_t *timep) ;
例子:
#include #include time_t get_utc_time (void ) { return time(NULL ); }int main (int argc, char **argv) { time_t utc_time = get_utc_time(); printf ("utc_time = %ld s\n" , utc_time); struct tm *gmt_tm = gmtime (&utc_time ); printf ("gmt time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n" , gmt_tm->tm_year + 1900 , gmt_tm->tm_mon + 1 , gmt_tm->tm_mday, gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec); return 0 ; }
编译、运行: