关于time_t
作者:sandy1 日期:2009-11-20
关于time_t
1. time_t用于表示一个绝对时间。其本质是一个unsigned int,保存的是自1970年1月1日0点0分0秒起所经过的秒数。
2.Unix中的世界末日:2038年1月19日,凌晨3点14分07秒。
嗯,因为32位字长的Unix,其unsigned int最多只能表示到2^32,于是从1970年1月1日0点0分0秒开始数够2^32秒后便到了头——这是Unix能表示的时间最大值。
3.__time32_t和__time64_t:由于2^32秒只能保存到2038年,因此你如果想让你的电脑在2039年还工作正常,你最好还是将保存时间的变量由32位扩充至64位。于是原来的time_t被搞成两种类型:__time32_t是老式的和Unix兼容的32位时间,__time64_t则是64位的时间。这样就可以保存到1970年以后的2^64秒的年月。不过鉴于我们还用不了那么遥远,于是windows下限定__time64_t最多表示到23:59:59, December 31, 3000。嗯,我想应该是够用了。
time_t会根据是否定义了_USE_32BIT_TIME_T宏来决定自己到底是到底是__time32_t还是__time64_t。
和TCHAR很像,两面派呵呵。
4.tm。鉴于time_t保存的秒数让大多数人使用困难(比如我给你345639你能说出是哪一年哪一月吗?),于是定义了一个tm类型来表示人能看懂的时间:
这个就把时间按照年月日时分秒分的很清楚了,人们使用起来就直观了。
关于最后一个字段tm_isdst解释下:这个是一个标志,表示是否启用夏令时。1表示启用,0表示不启用,国内一般不怎么用了。(你那里用夏令时吗?)
5.tm <---> time_t
提供了这么几个函数来达到二者的互相转换:
6.mktime的实现。
想想mktime干了些什么:将年月日时分秒换算成了自1970年1月1日以来的秒数。这其中有多少需要考虑的:年有闰年和非闰年之分,而一个月有31天的,还有30天的,还有28、29天的……真是复杂。
不过自有牛人来完成这个壮举:
这是Linux下的mktime实现,就在这么短短几行之内完成了如此复杂的换算。里面一些magic number估计都会让你眼花缭乱了。如果想仔细剖析这个代码的原理,请看这里:http://blog.csdn.net/axx1611/archive/2007/09/20/1792827.aspx
1. time_t用于表示一个绝对时间。其本质是一个unsigned int,保存的是自1970年1月1日0点0分0秒起所经过的秒数。
2.Unix中的世界末日:2038年1月19日,凌晨3点14分07秒。
嗯,因为32位字长的Unix,其unsigned int最多只能表示到2^32,于是从1970年1月1日0点0分0秒开始数够2^32秒后便到了头——这是Unix能表示的时间最大值。
3.__time32_t和__time64_t:由于2^32秒只能保存到2038年,因此你如果想让你的电脑在2039年还工作正常,你最好还是将保存时间的变量由32位扩充至64位。于是原来的time_t被搞成两种类型:__time32_t是老式的和Unix兼容的32位时间,__time64_t则是64位的时间。这样就可以保存到1970年以后的2^64秒的年月。不过鉴于我们还用不了那么遥远,于是windows下限定__time64_t最多表示到23:59:59, December 31, 3000。嗯,我想应该是够用了。
time_t会根据是否定义了_USE_32BIT_TIME_T宏来决定自己到底是到底是__time32_t还是__time64_t。
和TCHAR很像,两面派呵呵。
4.tm。鉴于time_t保存的秒数让大多数人使用困难(比如我给你345639你能说出是哪一年哪一月吗?),于是定义了一个tm类型来表示人能看懂的时间:
| C++ 代码: |
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 */
};
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 */
};
这个就把时间按照年月日时分秒分的很清楚了,人们使用起来就直观了。
关于最后一个字段tm_isdst解释下:这个是一个标志,表示是否启用夏令时。1表示启用,0表示不启用,国内一般不怎么用了。(你那里用夏令时吗?)
5.tm <---> time_t
提供了这么几个函数来达到二者的互相转换:
| gmtime | 将time_t转换成tm。传入一个time_t,传出一个tm。 |
| localtime | 将time_t转换成tm。不过这里假定time_t是一个UTC(世界标准时间),转换出来的tm是当地时间,已经经过了时区调整。(比如你在中国,是东8区,因此+8个小时) |
| mktime | 将tm转换成time_t。传入一个tm,传出一个time_t。假定传入的是当地时间,会将其调整成UTC。(注意这时tm中的tm_wday和tm_yday两项会被忽略) |
| _mkgmtime* | 将tm转换成time_t。不进行时区调整。不过此函数只有VC才带有,标准time.h中没有。 |
6.mktime的实现。
想想mktime干了些什么:将年月日时分秒换算成了自1970年1月1日以来的秒数。这其中有多少需要考虑的:年有闰年和非闰年之分,而一个月有31天的,还有30天的,还有28、29天的……真是复杂。
不过自有牛人来完成这个壮举:
| C++ 代码: |
static inline unsigned long mktime (unsigned int year, unsigned int mon,
unsigned int day, unsigned int hour,
unsigned int min, unsigned int sec)
...{
if (0 >= (int) (mon -= 2)) ...{ /**//* 1..12 -> 11,12,1..10 */
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 */
}
unsigned int day, unsigned int hour,
unsigned int min, unsigned int sec)
...{
if (0 >= (int) (mon -= 2)) ...{ /**//* 1..12 -> 11,12,1..10 */
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 */
}
这是Linux下的mktime实现,就在这么短短几行之内完成了如此复杂的换算。里面一些magic number估计都会让你眼花缭乱了。如果想仔细剖析这个代码的原理,请看这里:http://blog.csdn.net/axx1611/archive/2007/09/20/1792827.aspx
评论: 1 | 引用: 0 | 查看次数: 358
回复
]magic number真是诡异阿。记得之前跟我看过的开方函数的magic number,完全没思路。
发表评论
上一篇
下一篇


文章来自:
Tags: 




