今天的任务是把日期(年月日时分秒)转换为秒(自1970年开始)
首先介绍struct tm 和 time_t
struct tm { int tm_sec; /* seconds after the minute - [0,59] */ int tm_min; /* minutes after the hour - [0,59] */ int tm_hour; /* hours since midnight - [0,23] */ int tm_mday; /* day of the month - [1,31] */ int tm_mon; /* months since January - [0,11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday - [0,6] */ int tm_yday; /* days since January 1 - [0,365] */ int tm_isdst; /* daylight savings time flag */ }; #ifdef _USE_32BIT_TIME_T typedef __time32_t time_t; /* time value */ #else typedef __time64_t time_t; /* time value */ #endif
time_t用于表示秒数(自1970.01.01.00:00:00) 其中32位的time_t可以表示的时间范围是[1970.01.01.00:00:00, 2038.01.18.19:14:07], 64位的time_t可以表示范围为:[1970.01.01.00:00:00, 3001.01.01.00:00:00)
tm用于表示日期
采用函数time_t mktime(struct tm *_Tm) 可以实现日期转换为秒。
采用函数time_t time(time_t *timer)可以获取当前系统时间相对与1970年1月1日已经走过的秒数
struct tm * gmtime(const time_t *timer); 把秒数转换为以格林威治时间为标准的日期。
struct tm * localtime(const time_t * timer); 把秒数转换为当地时间为标准的日期。
输出时间和日期:
char * asctime(const struct tm * timeptr);
char * ctime(const time_t *timer);
两者均以相同的格式输出: 星期 月份 日期 时:分:秒 年\n\0 例如:
Wed Jan 02 02:03:55 1980\n\0
其实asctime函数只是很简单地提取tm中的参数
而ctime则需要先把时间转换为本地时间为标准的日期,然后再调用asctime函数
ctime(&t) 相当于:
tm TM = localtime(&t);
ctime(&TM);
例子:
#include <stdio.h> #include <time.h> int main() { time_t t = time(NULL); printf("the seconds since 1970 : %I64d\n", t); tm *TM; TM = localtime(&t); printf("the date today is : %s",asctime(TM)); printf("the date today is : %s",ctime(&t)); return 0; }
localtime和gmtime,不是线程安全的,我们可以用localtime_r和gmtime_r代替
struct tm* localtime_r( const time_t* timer, struct tm* result );
如果想自己实现时间与日期的转换,可以参考下Linux内核下的mktime()函数
unsigned long mktime(const unsigned int year0, const unsigned int mon0, const unsigned int day, const unsigned int hour, const unsigned int min, const unsigned int sec) { unsigned int mon = mon0, year = year0; /* 1..12 -> 11,12,1..10 */ if (0 >= (int) (mon -= 2)) { mon += 12; /* Puts Feb last since it has leap day */ year -= 1; } return ((((unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) + year*365 - 719499 )*24 + hour /* now have hours */ )*60 + min /* now have minutes */ )*60 + sec; /* finally seconds */ }
以下是介绍这个算法的一篇文章。。表示没看懂。自己试过以后,好像也不太准,莫非打开方式不正确?求强大的程序猿解答>.<
http://www.linuxidc.com/Linux/2011-08/41854.htm