上一篇的一个遗留问题,是有关时间的可读性问题,毕竟用整数来表示时间太不直观。
linux 有关时间的类型和函数在 time.h 这个头文件中。接下来,我们主要介绍两个与时间相关的类型(time_t 和 struct tm)以及三个函数(gmtime 、 localtime 和 mktime).
知识点:
- 两个类型
- time_t
- struct tm
- 三个函数
- gmtime
- localtime
- mktime
1 两个类型
1.1 time_t 类型
linux 中,使用了 time_t 类型来描述时间。本质上它是一个 long 类型。
typedef long time_t
time_t 描述的时间是从 1970年1月1日00时00分00秒到获取时间的那一刻的秒数。比如 time_t x = 70,变量 x 表示的时间就是1970年1月1日00时01分10秒。
通过 time(NULL)
函数可以获取当前时间,并以 time_t 类型返回。
1.2 tm 结构体
time_t 描述的时间不能被人类直观解读,但是 linux c 提供了一个名为 tm 的结构体,这个结构体就显得人性化多了。
struct tm{
int tm_sec; /*秒 - 取值区间为[0, 59]*/
int tm_min; /*分 - 取值区间为[0, 59]*/
int tm_hour; /*时 - 取值区间为[0, 23]*/
int tm_mday; /*日 - 取值区间为[1, 31]*/
int tm_mon; /*月份 - 取值区间为[0, 11]*/
int tm_year; /*年份 - 其值为1900年至今年数*/
int tm_wday; /*星期 - 取值区间[0, 6],0代表星期天,1代表星期1,以此类推*/
int tm_yday; /*从每年的1月1日开始的天数-取值区间为[0, 365],0代表1月1日*/
int tm_isdst; /*夏令时标识符,使用夏令时,tm_isdst为正,不使用夏令时,tm_isdst为0,不了解情况时,tm_isdst为负*/
};
2 time_t 到 tm 的转换
只要能够把 time_t 转换成 tm 类型,那么一切就好说了。说转换可能不太准确,说根据 time_t 类型获取 tm 类型的数据比较恰当。
linux 提供了两种函数,用来把 time_t 类型时间转换成 tm 结构体,分别是:
tm* gmtime(time_t *p)
tm* localtime(time_t *p)
这两个函数唯一的区别就是,gmtime 获取的是格林尼治时间,localtime 获取的是当地时区的时间,比如我们获取的就是东八区的北京时间。所以 localtime 获取的时间 = GMT时间+8。
3 tm 到 time_t 的转换
linux 也提供了将 tm 结构体转换成 time_t 的函数:
time_t mktime(struct tm *p_tm);
这个函数可以把当地时间转换成 time_t 类型。
4 实例
- 代码
#include <time.h>
#include <stdio.h>
int main() {
char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
time_t t = time(NULL); // 获取当前时间
printf("time_t = %ld\n\n", t);
struct tm *tt = gmtime(&t); // 转换成格林尼治时间
printf("gmtime:\n");
printf("%d-%d-%d ", (tt->tm_year+1900), (tt->tm_mon+1), tt->tm_mday);
printf("%s %d:%d:%d\n\n", wday[tt->tm_wday], tt->tm_hour, tt->tm_min, tt->tm_sec);
tt = localtime(&t); // 转换成当地时间
printf("localtime:\n");
printf("%d-%d-%d ", (tt->tm_year+1900), (tt->tm_mon+1), tt->tm_mday);
printf("%s %d:%d:%d\n\n", wday[tt->tm_wday], tt->tm_hour, tt->tm_min, tt->tm_sec);
time_t ttt = mktime(tt); // 将当地时间转换回 time_t 类型
printf("mktime:\n");
printf("time_t = %ld\n", ttt);
return 0;
}
- 编译
$ gcc timedemo.c -o tm
- 运行
$ ./tm
- 结果
time_t = 1480484733
gmtime:
2016-11-30 Wed 5:45:33
localtime:
2016-11-30 Wed 13:45:33
mktime:
time_t = 1480484733
5 总结
本篇需要掌握的知识点:
time_t
类型struct tm
类型gmtime
和localtime
函数- mktime 函数
当然,linux 时间处理的类型和函数远远不止这些,具体可以参考后面列举的资料。
参考文献:
[1] linux 时间函数
[2] Linux下面time.h时间函数总结