一、三个概念:
(1)UTC/GMT:Coorainated Universal Time:它是一个标准,最主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林尼治平时,也即格林威治标准时间(Greenwich Mean Time,GMT),在大多数场合,UTC与GMT等同(只是GMT不再由科学界精确定义)。
注:为描述方便,本文中将UTC与GMT等同。
(2)Local time:指相对于UTC/GMT时间的本地时间(时区转换)。比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5。
(3)Calendar time:日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。在计算机中是相对于时间点:1970年1月1日,来算的。
二、主要数据类型、结构及函数(头文件:<ctime> (或者 time.h))
(1)types:
time_t:time type,通常为整型值,表示自1970年1月1日00:00到现在所经过的秒数。
typedef long time_t
struct tm:time structure,该结构体包含了日历时间和日期,其中各成员详细信息如下:
注:1,tm_year是指自1900年后的个数,故要得出真正的年份,还有加上1900(即tm_year + 1900)。2,tm_isdst指夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。但中国不实行夏令时,即此处应该0.
(2)functions:(以下只挑选了几个有代表性的函数为的是理清思路,更多函数可参考C++手册)
函数名:time
原型:time_t time (time_t* timer):
功能:获取当前的日历时间。若 timer 为NULL,则返回日历时间;若timer非NULL则将获取的日历时间存于timer中。
函数名:gmtime:
原型:struct tm* gmtime (const time_t* timer);
功能:将time_t类型的日历时间转换为 tm 结构的UTC(GMT)时间。
函数名:localtime
原型:struct tm* localtime (const time_t* timer);
功能:将time_t类型的日历时间转换为 tm 结构的 Local time(本地时间)。
函数名:ctime
原型:char* ctime (const time_t* timer);
功能:将time_t类型的日历时间转换为适合人们阅读(human-readable)的字符串格式的时间。
函数名:mktime
原型:time_t mktime (const struct tm* timeptr);
功能:将tm结构体类型的时间转换为 time_t类型的时间
函数名:asctime
原型:char* asctime (const struct tm* timeptr);
功能:将tm结构体类型的时间转换为适合人们阅读的字符串格式的时间。
综上,可以发现时间的表示形式不外乎三种:time_t、strcut tm以及string(char*).
三、例子
#include<iostream>
#include<string>
#include<ctime>
using namespace std;
int main()
{
time_t rawtime = time(NULL);
cout<<"rawtime:"<<rawtime<<endl;
struct tm localtm = *localtime(&rawtime);
struct tm UTCtm = *gmtime(&rawtime);
cout<<"----------UTC time VS local time-----------"<<endl;
cout<<"tm_sec: "<<localtm.tm_sec<<" "<<UTCtm.tm_sec<<endl;
cout<<"tm_min: "<<localtm.tm_min<<" "<<UTCtm.tm_min<<endl;
cout<<"tm_hour: "<<localtm.tm_hour<<" "<<UTCtm.tm_hour<<endl;
cout<<"tm_mday: "<<localtm.tm_mday<<" "<<UTCtm.tm_mday<<endl;
cout<<"tm_mon: "<<localtm.tm_mon+1<<" "<<UTCtm.tm_mon+1<<endl;
cout<<"tm_year: "<<localtm.tm_year+1900<<" "<<UTCtm.tm_year+1900<<endl;
cout<<"tm_yday: "<<localtm.tm_yday<<" "<<UTCtm.tm_yday<<endl;
cout<<"tm_isdst: "<<localtm.tm_isdst<<" "<<UTCtm.tm_isdst<<endl;
string cstime = asctime(&localtm);
cout<<"string time:"<<cstime<<endl;
time_t makeLocal = mktime(&localtm);
cout<<"mktime (hours)local: "<<makeLocal/3600<<endl;
time_t makeUTC = mktime(&UTCtm);
cout<<"mktime (hours)UTC: "<<makeUTC/3600<<endl;
return 0;
}
输出结果:
注:由结果可知,local time(UTC+8)比UTC要大8个小时,而其他member均一样。
四、关于localtime的返回值的内存问题:
在执行localtime(或者是gmtime或者是mktime等)时,有一个小问题。注意到代码中的:
struct tm localtm =*localtime(&rawtime);
struct tm UTCtm = *gmtime(&rawtime);
当我们写成:
struct tm* localtmptr = localtime(&rawtime);
struct tm*UTCtmptr = gmtime(&rawtime);
则会出现问题,运行结果会发现又localtime和gmtime得出的时间值时一样的,它们之间并不相差8个小时。
为什么会这样呢?
通过man localtime命令,可以发现一些细节:
即 localtime(或者是gmtime或者是mktime)等,它们的返回值都是指向一个共享的静态存储区,该块内存可能会被后面的时间函数重写。故 若有时间函数连续出现时,应该直接返回该内存,而不是指向该内存的指针。
这样一来,每一个时间函数都会从静态存储区把自己的时间拷贝出来,存入自己的内存区。