当通过time
函数获取系统时间的时候,time_t
得到的是一个计算机系统时间是按照UTC时间计算的从1970年1月1日0时开始的秒数。因此,在当前某一时刻,无论运行的计算机在地球哪个时区,其通过time(NULL)
函数获得的time_t
的值都是相同的。
将time_t
转换为可读的本地时间格式用localtime
函数。
将time_t
转换为可读的UTC时间格式用gmtime
函数。
既然计算机的time_t
使用统一的UTC时间基准计时。在struct tm
对象到time_t
时,却只提供了一个转换函数:mktime
函数。但是它却是把本地时间格式的struct tm
对象转到time_t
(注意,time_t
只有UTC格式)。为何没有UTC时间格式的转换函数?(本文无答案)。
我们通过下面的程序验证:
#include
#include
time_t tp = 0;
time_t tn = 0;
struct tm *tmp = 0;
time(&tp);
printf("time():%d\n",tp);
tmp = localtime(&tp);
tn = mktime(tmp);
printf("time()->localtime()->mktime(): %d\n", tn);
tmp = gmtime(&tp);
tn = mktime(tmp);
printf("time()->gmtime()->mktime(): %d\n", tn);
运行结果:
time(): 1659079214
time()->localtime()->mktime(): 1659079214
time()->gmtime()->mktime(): 1659050414
查阅文档得知,mktime
函数是将struct tm
对象作为本地时间转换为time_t
。
参考:
当我们在处理涉及全球时间的程序时,分2种情况(此处仅讨论Windows和Linux):
time_t
的值是从time(NULL)
函数或者已知为本地系统时间而来,则需要用gmtime
函数来转换为struct tm
对象。time_t
的值是从其他已知的UTC时间而来,则需要用localtime
函数来转换为struct tm
对象。如果需要将struct tm
格式的时间转换为time_t
,而struct tm
对象如果不是本地时间,则需要在mktime
执行以后,加上一个本地时间到UTC时间的偏移秒数。
如果需要处理其他时区的时间,可以使用boost的local_time。他可以获得不同时区与UTC的时间差,还可以在不同时区直接用boost::local_date_time::local_time_in (boost::local_time::time_zone_ptr)
函数从一个时区的时间转换为另一个时区的时间。并且可以处理烦人的冬夏令时。
#include "boost/date_time/local_time/local_time.hpp"
boost::local_time::tz_database tz_db;
const char* filename = "date_time_zonespec.csv";
tz_db.load_from_file(filename);
const char* region = "America/New_York";
boost::local_time::time_zone_ptr tz = tz_db.time_zone_from_region(region);
boost::posix_time::ptime t(boost::posix_time::second_clock::universal_time());
boost::local_time::local_date_time dt(t, tz);
auto t1 = dt.local_time();
auto td = t1 - t; // 这是指定时区和UTC时区相差的秒数
参考:
https://www.boost.org/doc/libs/1_78_0/doc/html/date_time/examples.html