日期与unix时间戳之间的转换C++实现

之前在https://blog.csdn.net/fengbingchun/article/details/107023645 中介绍过gmtime和localtime的区别,这里介绍下日期与Unix时间戳之间转换的实现,其中也会用到这两个函数。

Unix时间戳(Unix timestamp):是一种时间表示方式,定义为从格林威治时间(Greenwich Mean Time, GMT)1970年01月01日00时00分00秒起至现在的总秒数。如果操作系统使用32位二进制数字表示时间,则此类系统的Unix时间戳最多可以使用到格林威治时间2038年01月19日03时14分07秒(二进制: 01111111 11111111 11111111 11111111)。

时区:地球上的区域使用同一个时间定义。由于世界各国家与地区经度不同,地方时也有所不同,因此会划分为不同的时区。正式的时区划分包括24个时区,每一时区由一个英文字母表示。每差一个时区,区时相差一个小时,相差多少个时区,就相差多少个小时。为了照顾到各地区的使用方便,又使其它地方的人容易将本地的时间换算到别的地方时间上去。有关国际会议决定将地球表面按经线从东到西,划成一个个区域,并且规定相邻区域的时间相差1小时。在同一区域内的东端和西端的人看到太阳升起的时间最多相差不过1小时。当人们跨过一个区域,就将自己的时钟校正1小时(向西减1小时,向东加1小时),跨过几个区域就加或减几小时。例如,中国东8区的时间总比泰国东7区的时间早1小时,而比日本东9区的时间晚1小时。因此,出国旅行的人,必须随时调整自己的手表,才能和当地时间相一致。凡向西走,每过一个时区,就要把表拨慢1小时(比如2点拨到1点);凡向东走,每过一个时区,就要把表拨快1小时(比如1点拨到2点)。并且规定英国(格林尼治天文台旧址)为本初子午线,即零度经线。

本地时间(locale time):可由localtime函数获得,在中国为UTC+08:00,或称北京时间或东八时区。

协调世界时(Coordinated Universal Time, UTC):或世界标准时间,UTC的表示方式为:年、月、日、时、分、秒,均用数字表示。可以认为格林威治时间就是协调世界时(GMT=UTC),格林威治时间和UTC时间均有秒数来计算。

C语言中一些常用的函数:

(1).time_t:时间类型,基础算术类型的别名,能够表示时间,通常是一个大整数值,该整数值表示自UTC时间1970年1月1日00:00:00时起经过的秒数(即Unix时间戳)。

(2).struct tm:时间结构体,包含日历日期和时间的结构体,该结构体包含int类型的9个成员。

(3).time:获取当前时间,返回time_t,如果参数不是空指针,还将此值设置为参数指向的对象。返回的值通常代表自1970年1月1日00:00:00时起经过的秒数(即本地时间的Unix时间戳)。

(4).ctime:将time_t转换为字符串,返回char*。此函数等价于asctime(localtime(time_t))。

(5).asctime:将tm结构体转换为字符串,返回char*。

(6).strftime:将tm结构体转换为字符串,返回size_t。

(7).localtime:将time_t转换为本地时间,返回tm结构体。

(8).gmtime:将time_t转换为UTC时间,返回tm结构体。

(9).difftime:计算两个time_t之间的时间差(以秒为单位),返回double。

(10).mktime:将tm结构体转换为time_t,返回类型为time_t,本地时间,如无法表示日历时间,则返回值为-1。

以上函数用法的测试代码段如下:

void test_time()
{
	time_t rawtime = time(nullptr); //time_t rawtime; time(&rawtime);

	struct tm* timeinfo = localtime(&rawtime);
	fprintf(stdout, "The current local date/time is: %s", asctime(timeinfo));

	timeinfo = gmtime(&rawtime);
	fprintf(stdout, "The current utc date/time is: %s", asctime(timeinfo));

	fprintf(stdout, "The current local date/time is: %s", ctime(&rawtime));

	timeinfo = localtime(&rawtime);
	timeinfo->tm_hour = timeinfo->tm_min = timeinfo->tm_sec = timeinfo->tm_mon = 0; timeinfo->tm_mday = 1;
	fprintf(stdout, "%.f seconds since new year in the current timezone\n", difftime(rawtime, mktime(timeinfo)));

	timeinfo = localtime(&rawtime);
	char buffer[64];
	strftime(buffer, 64, "Now it's %I:%M%p", timeinfo);
	fprintf(stdout, "buffer: %s\n", buffer);
}

执行结果如下:

下面测试代码段是本地时间的日期与时间戳之间的转换:可通过localtime和mktime函数实现

void test_date_to_timestamp_local()
{
	// timestamp --> date
	time_t timestamp = time(nullptr);
	struct tm* timeinfo = localtime(&timestamp);
	int year = timeinfo->tm_year + 1900; // years since 1900
	int month = timeinfo->tm_mon + 1; // monthes since January - [0, 11]
	int day = timeinfo->tm_mday;
	int date = year * 10000 + month * 100 + day;
	int hour = timeinfo->tm_hour;
	int minute = timeinfo->tm_min;
	int second = timeinfo->tm_sec;
	fprintf(stdout, "timestamp: %ld, date: %d %.2d:%.2d:%.2d\n", timestamp, date, hour, minute, second);

	// date --> timestamp
	int date2 = 20211122;
	struct tm timeinfo2;
	memset(&timeinfo2, 0, sizeof(struct tm));
	timeinfo2.tm_year = date2 / 10000 - 1900;
	timeinfo2.tm_mon = date2 % 10000 / 100 - 1;
	timeinfo2.tm_mday = date2 % 100;
	time_t timestamp2 = mktime(&timeinfo2);
	fprintf(stdout, "date2: %d, timestamp2: %ld\n", date2, timestamp2);
}

执行结果如下:

下面测试代码段是UTC的日期与时间戳之间的转换:Linux下通过gmtime和timegm函数,Windows下通过gmtime和_mkgmtime函数。

#ifdef _MSC_VER
#define timegm _mkgmtime
#endif

void test_date_to_timestamp_utc()
{
	// timestamp --> date
	time_t timestamp = 86470; // 1day = 24 * 60 * 60 = 86400
	struct tm* timeinfo = gmtime(&timestamp);
	int year = timeinfo->tm_year + 1900; // years since 1900
	int month = timeinfo->tm_mon + 1; // monthes since January - [0, 11]
	int day = timeinfo->tm_mday;
	int date = year * 10000 + month * 100 + day;
	int hour = timeinfo->tm_hour;
	int minute = timeinfo->tm_min;
	int second = timeinfo->tm_sec;
	fprintf(stdout, "timestamp: %ld, date: %d %.2d:%.2d:%.2d\n", timestamp, date, hour, minute, second);

	// date --> timestamp
	int date2 = 19700102;
	struct tm timeinfo2;
	memset(&timeinfo2, 0, sizeof(struct tm));
	timeinfo2.tm_year = date2 / 10000 - 1900;
	timeinfo2.tm_mon = date2 % 10000 / 100 - 1;
	timeinfo2.tm_mday = date2 % 100;
	time_t timestamp2 = timegm(&timeinfo2);
	fprintf(stdout, "date2: %d, timestamp2: %ld\n", date2, timestamp2);
}

执行结果如下:

GitHubhttps://github.com/fengbingchun/Messy_Test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值