当前位置:首页>Linux>还在傻傻分不清楚Linux中各种时间变量?

还在傻傻分不清楚Linux中各种时间变量?

  • 2026-09-02 19:35:46
还在傻傻分不清楚Linux中各种时间变量?

【摘要】本文旨在说明在Linux中各种时间相关的变量定义,以及他们之间的转换函数。

一、时间类型

  • linux中常见的时间类型共有4类:

    • time_t

    • struct timeval

    • struct timespec

    • struct tm

  • time_t:由UNIX内核提供的基本时间服务是国际标准时间公元1970年1月1日00:00:00以来经过的秒数。我们称它们为日历时间,包括时间和日期。

  • struct  timeval:提供秒和微秒单位,最高精度是微秒。

/* A time value that is accurate to the nearest 
microsecond but also has a range of years. */
struct timeval
{    
__time_t tv_sec;       /* Seconds */
__suseconds_t tv_usec; /* Microseconds */
};
  • struct   timespec:提供秒和纳秒单位,最高精度是纳秒

struct timespec
{    
__time_t tv_sec;           /* Seconds.  */
__syscall_slong_t tv_nsec; /* Nanoseconds.  */
};
  • struct   tm:详细时间的结构体

struct tm
{  
int tm_sec;/* Seconds.[0-60] (秒超过59的理由是表示润秒) */
int tm_min;/* Minutes.[0-59] */
int tm_hour;/* Hours.[0-23] */
int tm_mday;/* Day.[1-31] (除了月日,其他字段的值都以 0开始)*/
int tm_mon;/* Month.[0-11] */
int tm_year;/* Year- 1900.  */
int tm_wday;/* Day of week.[0-6] */
int tm_yday;/* Days in year.[0-365]*/
int tm_isdst;/* DST.[-1/0/1]代表[不可用/非夏时制/夏时制]*/

# ifdef __USE_MISC  
long int tm_gmtoff;/* Seconds east of UTC.  */
const char* tm_zone;/* Timezone abbreviation.  */
# else  
long int __tm_gmtoff;/* Seconds east of UTC.  */
const char *__tm_zone;/* Timezone abbreviation.  */
# endif
};

  • 时区

    struct timezone {
    int tz_minuteswest;     /* minutes west of Greenwich */
    int tz_dsttime;         /* type of DST correction,linux中不支持,应该置为0 */
    };

二、时间函数

(一) 获取/设置 秒级 精度的日历时间

//取得从1970年1月1日至今的秒数
//例如:time_t totalsec = time(NULL);或time(&totalsec); 
time_t time(time_t *t);

//修改系统时间,注意只有root用户才有修改系统时间的权限
int stime(time_t *t);

(二) 获取/设置 微秒级 精度的日历时间

//系统函数,返回自1970年以来的秒数和微秒数,后面的tz是时区,一般不用。
int gettimeofday(struct timeval *tv, struct timezone *tz);

//系统函数,为系统设置当前时间;后面的tz通常设为NULL,表示使用当前系统的时区
int settimeofday(struct timeval *tv, struct timezone *tz);

(三)获取/设置 纳秒级 精度的日历时间

int clock_gettime(clockid_t clk_id, struct timespec *tp);
/*根据需要,获取不同要求的精确时间
参数clk_id可取以下值: 
CLOCK_REALTIME:系统实时时间,随系统实时时间改变而改变,即从UTC1970-1-1 0:0:0开始计时,中间时刻如果系统时间被用户改成其他,则对应的时间相应改变
CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响
CLOCK_PROCESS_CPUTIME_ID:本进程到当前代码系统CPU花费的时间
CLOCK_THREAD_CPUTIME_ID:本线程到当前代码系统CPU花费的时间
*/

(四)日历时间——>本地时间

//将time_t表示的时间转换为没有经过时区转换的UTC时间
struct tm* gmtime(const time_t *timep);

//和gmtime类似,但是它是经过时区转换的时间。
struct tm* localtime(const time_t *timep);

(五)本地时间——>日历时间

//将struct tm 结构的时间转换为日历时间(从1970年至今的秒数)
time_t mktime(struct tm *timeptr);

(六)获取字符串形式的时间

char* asctime(const struct tm *timeptr); 
//将结构中的信息转换为真实世界的UTC时间,以字符串的形式显示 

char* ctime(const time_t *timep);
//作用同asctime,不同点仅在于传入的参数类型不同 

size_t strftime(char *buf, size_t maxsize, const char *format, const struct tm *tmptr);
//将tmptr指向的tm本地时间转化为format格式的字符串,并存入buf中,返回字符串长度。
/* 格式意义例子
__________________________________________________
%a 缩写的周日名Tue
%A 全周日名 Tuesday
%b 缩写的月名 Jan
%B 月全名  January
%c 日期和时间 Tue Jan 14 19:40:30 1992
%d 月日:[01, 31] 14
%H 小时(每天2 4小时):[00, 23] 19
%I 小时(上下午各12小时):[01, 12]07
%j 年日:[001, 366] 0 14
%m 月:[01, 12]  01
%M 分:[00, 59]  40
%p AM/PM  PM
%S 秒:[00, 61]  30
%U 星期日周数:[00, 53]   02包含该年中第一个星期日的周是第一周
%w 周日:[ 0=星期日,6 ]  2
%W 星期一周数:[00, 53]  02包含第一个星期一的周为第一周
%x 日期 01/14/92
%X 时间 19:40:30
%y 不带公元的年:[00, 991] 92
%Y 带公元的年 1992
%Z 时区名    MST
__________________________________________________
*/

(七)其它

//返回两个时间相差的秒数 
double difftime(time_t time1, time_t time2);

Linux时间转换图:

  • 注意:localtime() , mktime() ,ctime()和strftime()这四个函数受到环境变量TZ的影响。即如果定义了TZ,则这些函数将使用其值以代替系统默认时区。 如果TZ定义为空串,则使用国际标准时间。TZ的值常常类似于:TZ = EST5EDT。

三、实例

  1. 设置系统时间:

struct timeval tv;
tv.tv_sec = (time_t)gps_utctime_sec;  
tv.tv_usec = 0;
if(settimeofday (&tv, NULL) <0){  
MSG("[ GPS ]:Set system datatime error,may need root permissions!\n");  
}
else
MSG("[ GPS ]:GPS valid,update system time!\n");
  1. 读取当前时间tick

/*! get the current system time tick, second unit */
static uint32_t getCurrSysTick(void)
{
time_t timep;
time (&timep);
return timep;  //seconds from 1970-1-1:0:0:0
}
  1. 读取当前时间字符串:Fri Dec 20 14:44:18 2019

static char* getCurrSysTime(void)
{
time_t timep;
time (&timep);
return asctime(localtime(&timep));
}
  1. 设置延时

static void delay_ms(unsigned int dms)
{
struct timespecsleeper, dummy ;
sleeper.tv_sec= (time_t)(dms/1000) ;
sleeper.tv_nsec= (long)(dms%1000) *1000000 ;
nanosleep (&sleeper, &dummy);//delay 1ms
}
  1. 获取当前时间tm

struct tm *t_tm; 
t_tm = localtime((time_t*)&meas_gps_utctime.tv_sec);
printf("today is %4d-%02d-%02d %02d:%02d:%02d\n",\
t_tm->tm_year+1900,
t_tm->tm_mon+1,
t_tm->tm_mday,
t_tm->tm_hour,
t_tm->tm_min,
t_tm->tm_sec);  

最新文章

随机文章