第七章 系统信息与系统资源(7.2.4-7.2.5)

本文详细介绍了C语言中的时间转换函数,如ctime(),localtime(),gmtime(),mktime(),asctime(),strftime()以及settimeofday(),展示了如何处理和格式化时间,以及settimeofday()如何设置系统时间的权限限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

7.2.4时间转换函数

        通过 time()或 gettimeofday()函数可以获取到当前时间点相对于 1970-01-01 00:00:00 +0000 (UTC)这个时间点所经过时间(日历时间),所以获取得到的是一个时间段的长度,但是这并不利于我们查看当前时间。
        本小节将向大家介绍一些系统调用或 C 库函数,通过这些 API 可以将 time()或 gettimeofday()函数获取到的秒数转换为利于查看和理解的形式。   

ctime 函数

         ctime()是一个 C 库函数,可以将日历时间转换为可打印输出的字符串形式。  

#include <time.h>
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);

/*函数参数如下:
    timep:time_t 时间变量指针。
返回值:
    成功将返回一个 char *类型指针,指向转换后得到的字符串;
    失败将返回 NULL。*/

        只需将 time_t 时间变量的指针传入即可,调用成功便可返回字符串指针,拿到字符串指针之后,可以使用 printf 将其打印输出。
        但是 ctime()是一个不可重入函数,存在一些安全上面的隐患。
        ctime_r()是 ctime()的可重入版本,一般推荐大家使用可重入函数 ctime_r()。
        可重入函数 ctime_r()多了一个参数 buf,也就是缓冲区首地址,所以 ctime_r()函数需要调用者提供用于存放字符串的缓冲区。

        ctime(或 ctime_r)转换得到的时间是计算机所在地对应的本地时间(譬如在中国对应的便是北京时间),并不是 UTC 时间。

localtime 函数

        localtime()函数可以把 time()或 gettimeofday()得到的秒数(time_t 时间或日历时间)变成一个 struct tm结构体所表示的时间,该时间对应的是本地时间。

#include <time.h>
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

/*函数参数:
    timep:需要进行转换的 time_t 时间变量对应的指针,可通过 time()或 gettimeofday()获取得到。
    result:是一个 struct tm 结构体类型指针,参数 result 是可重入函数
    localtime_r()需要额外提供的参数。
返回值:
    对于不可重入版本 localtime()来说,
        成功则返回一个有效的 struct tm 结构体指针,
    而对于可重入版本 localtime_r()来说,
        成功执行情况下,返回值将会等于参数 result;
        失败则返回 NULL。*/

        不可重入函数 localtime()并不需要调用者提供 struct tm 变量,而是它会直接返回出来一个 struct tm结构体指针,然后直接通过该指针访问里边的成员变量即可!虽然很方便,但是存在一些安全隐患,所以一般不推荐使用不可重入版本。
        可重入版本 localtime_r()调用者需要自己定义 struct tm 结构体变量、并将该变量指针赋值给参数result,在函数内部会对该结构体变量进行赋值操作。

        struct tm 结构体如下所示:

struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;    /* 年(这个值表示的是自 1900 年到现在经过的年数) */
int tm_wday;    /* 星期(0-6, 星期日 Sunday = 0、星期一=1...) */
int tm_yday;    /* 一年里的第几天(0-365, 1 Jan = 0) */
int tm_isdst;    /* 夏令时 */
}

        从 struct tm 结构体内容可知,该结构体中包含了年月日时分秒星期等信息,使用 localtime /localtime_r()便可以将 time_t 时间总秒数分解成了各个独立的时间信息。

gmtime 函数

        gmtime()函数也可以把 time_t 时间变成一个 struct tm 结构体所表示的时间,与 localtime()所不同的是,gmtime()函数所得到的是 UTC 国际标准时间,并不是计算机的本地时间,这是它们之间的唯一区别。

mktime 函数

        mktime()可以将使用 struct tm 结构体表示的分解时间转换为 time_t时间(日历时间)  。

#include <time.h>
time_t mktime(struct tm *tm);

/*函数参数:
    tm:需要进行转换的 struct tm 结构体变量对应的指针。
返回值:
    成功返回转换得到 time_t 时间值;
    失败返回-1。*/

asctime 函数  

        asctime()函数与 ctime()函数的作用一样,也可将时间转换为可打印输出的字符串形式,与 ctime()函数的区别在于:
        ctime()是将 time_t 时间转换为固定格式字符串、
        asctime()则是将 struct tm 表示的分解时间转换为固定格式的字符串。

#include <time.h>
char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);

/*函数参数:
    tm:需要进行转换的 struct tm 表示的时间。
    buf:可重入版本函数 asctime_r 需要额外提供的参数 buf,指向一个缓冲区,
        用于存放转换得到的字符串。
返回值:
    转换失败将返回 NULL;
    成功将返回一个 char *类型指针,指向转换后得到的时间字符串,
对于 asctime_r 函数来说,返回值就等于参数 buf。*/

strftime 函数

        strftime()函数也可以将一个 struct tm 变量表示的分解时间转换为为格式化字符串,并且在功能上比 asctime()和 ctime()更加强大,它可以根据自己的喜好自定义时间的显示格式,而 asctime()和 ctime()转换得到的字符串时间格式的固定的。

        strftime 函数的特殊格式说明符还是比较多的,不用去记它,需要用的时候再去查即可。

7.2.5 设置时间 settimeofday

        使用 settimeofday()函数可以设置时间,也就是设置系统的本地时间。      

#include <sys/time.h>
int settimeofday(const struct timeval *tv, const struct timezone *tz);

/*函数参数:
    tv:参数 tv 是一个 struct timeval 结构体指针变量,struct timeval 结构体在前面章节内容中已经给大家介绍了,需要设置的时间便通过参数 tv 指向的 struct timeval 结构体变量传递进去。
    tz:参数 tz 是个历史产物,早期实现用其来设置系统的时区信息,目前已遭废弃,在调用 settimeofday()
函数时应将参数 tz 设置为 NULL。
返回值:
    成功返回 0;
    失败将返回-1,并设置 errno。*/

        使用 settimeofday 设置系统时间时内核会进行权限检查,只有超级用户(root)才可以设置系统时间,普通用户将无操作权限。

        系统时间部分总结图。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值