入门Linux时间管理,这7个接口帮你搞定
时间:2025-04-20 22:03:46 138浏览 收藏
本文系统讲解了Linux下7个时间管理接口:`time`、`gettimeofday`、`clock_gettime`、`times`、`stime`、`settimeofday`和`clock_settime`,涵盖了时间获取和设置两种操作。文章深入探讨了Linux时间表示形式(相对时间、绝对时间)、相关结构体(`time_t`、`timeval`、`timespec`、`tm`)以及各个接口的函数原型、功能描述、返回值和注意事项,并通过实例测试验证了`time/stime`、`gettimeofday/settimeofday`以及`clock_gettime/clock_settime`接口的使用方法,旨在帮助读者深入理解和掌握Linux时间管理。 文末提供源码获取方式,欢迎关注公众号获取更多干货文章。
7个设置/获取接口了解Linux时间管理引言最近的项目开发中,频繁遇到了时间戳相关的问题,如时间回退至1970年、时区错误及时间同步不准确等。鉴于此前仅对时间接口的使用有所了解而未深入探究其原理,本篇文章进行一次系统性整理,以便后续参考。文章若存在一些错误,可在留言区明确指出。
注:文末提供本文源码获取方式。文章不定时更新,喜欢本公众号系列文章,可以星标公众号,避免遗漏干货文章。源码开源,如果对您有帮助,帮忙分享、点赞加收藏喔!
基础概念Linux 中的时间形式主要以两种形式呈现:
相对时间 指相对于某个基准点来衡量时间流逝。通常用于描述进程运行的时间或两个事件之间的时间差。进程时间
即进程消耗的时间,包含用户空间代码运行的时间和在内核在该进程消耗的时间(不包括进程被挂起或停止的时间)。单调时间
是一种始终递增的时间计数器,不受系统时钟调整的影响,常用于计算程序内部的持续时间。绝对时间 指具体的日期和时刻,它与地球上的特定时间标准相关联。GMT(Greenwich Mean Time 格林威治时间)
基于英国伦敦附近的格林尼治天文台的本初子午线的标准时间UTC(Universal Time Coordinated 世界标准时间)
一种国际标准时间,与GMT几乎相同,但更精确,用于避免地球自转速度变化带来的影响本地时间
根据用户所在地理位置所采用的时间,会随地理位置的不同而有所差异,同时也会受到夏令时等因素的影响相关结构体 时间编程中常用要用到的时间结构体有time_t
、timeval
、timespec
、tm
。《Unix环境高级编程》中一张图准确的反应出time_t
和tm
之间的关系:

时间函数之间的关系
time_t
:最简单的数据湖结构,表示从1970年1月1日00:00:00
UTC到现在的秒数。tm
:包含日期和时间的具体组成部分(年、月、日、时、分、秒等),通常由time_t
转换而来,用于显示或解析时间。timeval
:微秒级精度,包含秒(tv_sec)和微秒(tv_usec)。timespec
:纳秒级精度,包含秒(tv_sec)和纳秒(tv_nsec)。clock_t
:表示程序执行过程中消耗的CPU时间,单位是CLOCKS_PER_SEC
。相关函数时间获取time:函数原型:time_t time(time_t *tloc)
;功能描述:该函数返回从1970年1月1日00:00:00 UTC
以来的秒数。如果tloc
不是NULL
,则返回的时间值也会存储在tloc
指向的位置。返回值:成功时返回当前时间(以秒为单位),失败时返回(time_t)(-1)
。gettimeofday:函数原型:int gettimeofday(struct timeval *tv, struct timezone *tz)
;功能描述:这个函数提供了比time()
更高的精度,可以获取当前时间精确到微秒。struct timeval
包含两个成员:tv_sec
(秒数)和tv_usec
(微秒数)。struct timezone
已经废弃,通常传入NULL
。返回值:成功时返回0
,出错时返回-1
,并设置errno
。clock_gettime:CLOCK_REALTIME
描述:系统实时钟,反映当前的实际时间。特点:受系统时间调整的影响。CLOCK_MONOTONIC
描述:单调时钟,从某个未指定的起点开始计时。特点:不受系统时间调整的影响,适合用于测量时间间隔。CLOCK_PROCESS_CPUTIME_ID
描述:当前进程的CPU时间。特点:包括用户态和内核态的CPU时间。CLOCK_THREAD_CPUTIME_ID描述:当前线程的CPU时间。 特点:仅包括当前线程的CPU时间。CLOCK_MONOTONIC_RAW
(可选)描述:高精度单调时钟,不受系统时间调整的影响。特点:提供更高的时间分辨率。CLOCK_REALTIME_COARSE
(可选)描述:较低精度的系统实时钟。特点:速度快,但精度较低。CLOCK_MONOTONIC_COARSE
(可选)描述:较低精度的单调时钟。特点:速度快,但精度较低。函数原型:int clock_gettime(clockid_t clk_id, struct timespec *tp)
;功能描述:此函数提供了更高的时间分辨率,可以获取纳秒级别的精度。struct timespec
包含两个成员:tv_sec
(秒数)和tv_nsec
(纳秒数)。clk_id
参数指定了要查询的时间源(带有“可选”指并非所有系统都必须支持):返回值:成功时返回0
,出错时返回-1
,并设置errno
。times:函数原型:clock_t times(struct tms *buf)
;功能描述:此函数用于获取进程所使用的时间信息,包括用户态和内核态下的运行时间。struct tms
包含四个成员:tms_utime
(用户态运行时间)、tms_stime
(内核态运行时间)、tms_cutime
(子进程用户态运行时间)、tms_cstime
(子进程内核态运行时间),所有时间都以时钟滴答数(clock ticks
)表示。返回值:成功时返回进程自开始执行以来所使用的时钟滴答数,若出错则返回-1L
。时间设置stime:函数原型:int stime(const time_t *t)
;功能描述:此函数用于将系统的实时钟设置为指定的时间。t
是一个指向time_t
类型变量的指针,该变量包含了自1970年1月1日00:00:00
UTC以来的秒数。返回值:成功时返回0
,失败时返回-1
,并设置errno
。注意事项:stime()
函数通常需要root权限才能执行,且至Linux 2.6.x
之后版本不推荐使用,本地glibc 2.35
实测已无法编译此函数。settimeofday:函数原型:int settimeofday(const struct timeval *tv, const struct timezone *tz)
;功能描述:此函数允许设置系统的实时时间和时区信息。tv
指向一个struct timeval
结构,该结构包含了秒数和微秒数,用来表示新的系统时间。tz
指向一个struct timezone
结构,该结构包含了分钟偏移量和夏令时标志位,不过在现代系统中,通常不需要设置时区信息,因此可以传递NULL
。返回值:成功时返回0
,失败时返回-1
,并设置errno
。注意事项:与stime()
类似,settimeofday()
也需要适当的权限才能改变系统时间。clock_settime:函数原型:int clock_settime(clockid_t clk_id, const struct timespec *tp)
;功能描述:此函数用于设置由clk_id
标识的时钟。tp
指向一个struct timespec
结构,该结构包含了秒数和纳秒数,可以用来非常精确地设置时间。通常只允许设置时间源CLOCK_REALTIME
(系统实时钟)。返回值:成功时返回0
,失败时返回-1
,并设置errno
。注意事项:修改系统实时钟通常需要root
权限,而其他类型的时钟通常不允许设置。时间转换asctime / asctime_r(tm -> char*)函数原型:char *asctime(const struct tm *timeptr); / char *asctime_r(const struct tm *timeptr, char *buf)
;功能描述:将struct tm
结构转换为字符串格式,格式为 "Sun Sep 16 01:03:52 1979\n
"。asctime_r
是线程安全版本。返回值:返回指向字符串的指针。注意事项:asctime
返回的字符串是静态分配的,多次调用会覆盖前一次的结果。mktime (tm -> time_t)函数原型:time_t mktime(struct tm *timeptr)
;功能描述:将struct tm
结构转换为time_t
类型的时间值。返回值:成功时返回time_t
类型的时间值,失败时返回(time_t)(-1)
。注意事项:mktime
可能会修改传入的struct tm
结构中的某些字段。ctime / ctime_r (time_t -> char*)函数原型:char *ctime(const time_t *timep); / char *ctime_r(const time_t *timep, char *buf)
;功能描述:将time_t
类型的时间值转换为字符串格式,格式为 "Sun Sep 16 01:03:52 1979\n
"。ctime_r
是线程安全版本。返回值:返回指向字符串的指针。注意事项:ctime
返回的字符串是静态分配的,多次调用会覆盖前一次的结果。gmtime / gmtime_r (time_t -> tm ) UTC函数原型:struct tm *gmtime(const time_t *timep); / struct tm *gmtime_r(const time_t *timep, struct tm *result)
;功能描述:将time_t
类型的时间值转换为 UTC 时间的struct tm
结构。gmtime_r
是线程安全版本。返回值:成功时返回指向struct tm
结构的指针,失败时返回NULL
。注意事项:gmtime
返回的struct tm
结构是静态分配的,多次调用会覆盖前一次的结果。localtime / localtime_r (time_t -> tm) 本地时间函数原型:struct tm *localtime(const time_t *timep); / struct tm *localtime_r(const time_t *timep, struct tm *result)
;功能描述:将time_t
类型的时间值转换为本地时间的struct tm
结构。localtime_r
是线程安全版本。返回值:成功时返回指向struct tm
结构的指针,失败时返回NULL
。注意事项:localtime
返回的struct tm
结构是静态分配的,多次调用会覆盖前一次的结果。difftime (time_t -> double)函数原型:double difftime(time_t time1, time_t time0)
;功能描述:计算两个time_t
类型的时间值之间的差值,以秒为单位。返回值:返回两个时间值之间的差值,以秒为单位。时间格式化strftime (tm -> char*)函数原型:size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr)
;功能描述:根据指定的格式字符串format
将struct tm
结构转换为字符串,并存储在str
中。最多写入maxsize
个字符(包括终止符\0
)。返回值:成功时返回实际写入的字符数(不包括终止符\0
),如果缓冲区太小无法容纳结果,则返回0
。注意事项:确保提供的缓冲区str
足够大,以避免溢出。时区设置 时区会影响到本地时间与UTC
时间之间的转换(即本地时间 = UTC + 时区)。 查阅了一些文档,目前Ubuntu上时区记录在路径/etc/localtime
,其通常为软链接,指向具体的时区文件,例如/etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai
。通过修改/etc/localtime
指向即可修改为对应的时区(/etc/timezone
也会记录当前时区,但似乎仅用于显示)。
time
代码语言:javascript代码运行次数:0运行复制timestamp : 1732452775ctime_r : 1732452775( 0) Sun Nov 24 07:52:55 2024gmtime_r : 1732470775( 18000) EST Sun Nov 24 12:52:55 2024localtime_r: 1732452775( 0) EST Sun Nov 24 07:52:55 2024strftime : 1732452775( 0) EST Sun Nov 24 07:52:55 2024
通过打印可看出时区已经显示EST
,与Asia/Shanghai
时区相差了13h。
wait_for
会随着时间跳变而异常。尽管印象中,不应该这样,其依赖的应该是相对时间即单调时间。经过查阅相关资料,发现gcc版本和glibc版本对wait_for都有影响,gcc >=10 且 glibc >= 2.30 才会对程序行为没有影响。最后用心感悟,认真记录,写好每一篇文章,分享每一框干货。
到这里,我们也就讲完了《入门Linux时间管理,这7个接口帮你搞定》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于time,gettimeofday,clock_gettime,settimeofday,clock_settime的知识点!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
288 收藏
-
397 收藏
-
424 收藏
-
376 收藏
-
418 收藏
-
107 收藏
-
373 收藏
-
189 收藏
-
335 收藏
-
124 收藏
-
369 收藏
-
178 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习