一、什么是Unix时间戳
1、Unix时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。
2、Unix时间戳需要先加上8个小时(即8 * 60 * 60 s)的秒数差,再进行转换得到北京时间。
3、实用工具传送门 → Unix时间戳和北京时间在线转换工具
二、应用C语言库函数
-
2.1、包含头文件 time.h
#include<time.h>
-
2.2、定义时间戳类型:time_t
/* 时间戳类型,单位为秒,与uint32_t类型一样 */ typedef unsigned int time_t;
-
2.3、时间结构体 :tm
struct tm { int tm_sec; /* 秒钟,范围 0-60,偶尔的闰秒 */ int tm_min; /* 分钟,范围 0-59 */ int tm_hour; /* 小时,范围 0-23*/ int tm_mday; /* 日,范围 1-31 */ int tm_mon; /* 月份,范围 0-11 */ int tm_year; /* 年份,自从1900年 */ int tm_wday; /* 星期,范围 0-6 */ int tm_yday; /* 一年的第几天,范围 0-365 */ int tm_isdst; /* 夏令时标志 */ };
-
注意:Unix时间戳和北京时间相互转换时,要进行时间修正:
1、Unix时间戳转换为北京时间前要进行时间补偿,要+(8 * 60 * 60) s
2、年份自1900算起,转换为实际年份,要+1900
3、月份范围0-11,转换为实际月份,要+1
4、一年的第几天,范围 0-365,转换为一年的第几天,要+1
-
-
2.4、库函数:struct tm *localtime(const time_t * )
/*************************************** ** 参数 :一个单位为秒的时间戳 ** 返回值 :一个时间结构体 ***************************************/ struct tm *localtime(const time_t * )
-
2.5、库函数:time_t mktime(struct tm *)
/*************************************** ** 参数 :一个时间结构体 ** 返回值 :一个单位为秒的时间戳 ***************************************/ time_t mktime(struct tm *)
注意:转换时不考虑tm结构的tm_wday和tm_yday,仅用tm_mday来决定日期。
三、C语言实现Unix时间戳与北京时间的相互转换
-
3.1、定义变量
// 北京时间结构体 typedef struct{ uint16_t year; // 年 uint8_t month; // 月 uint8_t day; // 日 uint8_t wday; // 星期几 uint8_t yday; // 一年里的第几天 uint8_t hour; // 时 uint8_t min; // 分 uint8_t sec; // 秒 }bj_time; // 定义一个北京时间结构体变量 bj_time bjtime; // 定义一个单位为秒的 Unix时间戳 time_t timestamp; /* 几个用于测试的时间戳和北京时间对应 Unix时间戳 北京时间 1609689918 = 2021-01-04 00:05:18 1632325810 = 2021-09-22 23:50:10 1660809978 = 2022-08-18 16:06:18 */
-
3.2、Unix时间戳转为北京时间
- 3.2.1、代码
/*************************************** ** 函数名: UnixToBeijingTime ** 参数 : unixtime 一个单位为秒的Unix时间戳 ** 用途 : 将Unix时间戳转为北京时间 ***************************************/ void UnixToBeijingTime(time_t unixtime) { // 定义一个时间结构体 struct tm *time; // 定义一个单位为秒的Unix时间戳 time_t unixtemp = unixtime; // 8个小时的时间补偿 unixtemp += 8 * 60 * 60; time = localtime(&unixtemp); bjtime.year = time->tm_year; // 年 bjtime.month = time->tm_mon; // 月 bjtime.day = time->tm_mday; // 日 bjtime.wday = time->tm_wday; // 星期几 bjtime.yday = time->tm_yday; // 一年里的第几天 bjtime.hour = time->tm_hour; // 时 bjtime.min = time->tm_min; // 分 bjtime.sec = time->tm_sec; // 秒 // 时间修正 bjtime.year += 1900; bjtime.month += 1; bjtime.yday += 1; printf("\n\r\tUnix时间戳:%d\n\r", unixtime); printf("\n\r\t日期:%d-%02d-%02d 第%d天 星期%d 时间:%02d:%02d:%02d\n\r", bjtime.year, bjtime.month, bjtime.day, bjtime.yday, bjtime.wday, bjtime.hour , bjtime.min, bjtime.sec); } int main(void) { timestamp = 1609689918; // 北京时间: 2021-01-04 00:05:18 UnixToBeijingTime(timestamp); while(1) { } }
- 3.2.2、运行结果
- 3.2.1、代码
- 3.3、北京时间转为Unix时间戳
-
3.3.1、代码
/*************************************** ** 函数名: BeijingTimeToUnix ** 参数 : bjtimeArr 北京时间数组 ** 用途 : 将北京时间转为Unix时间戳 ***************************************/ void BeijingTimeToUnix(uint8_t* bjtimeArr) { // 定义一个时间结构体 struct tm time; // 定义一个单位为秒的Unix时间戳 time_t unixtemp; // 时间修正 time.tm_year = bjtimeArr[0] + 2000 - 1900; // 年 time.tm_mon = bjtimeArr[1] - 1; // 月 time.tm_mday = bjtimeArr[2]; // 日 time.tm_hour = bjtimeArr[3]; // 时 time.tm_min = bjtimeArr[4]; // 分 time.tm_sec = bjtimeArr[5]; // 秒 unixtemp = mktime(&time); // 8个小时的时间补偿 unixtemp -= 8 * 60 * 60; printf("\n\r\tUnix时间戳:%d\n\r", unixtemp); printf("\n\r\t日期:%d-%02d-%02d 时间:%02d:%02d:%02d\n\r", bjtimeArr[0] + 2000, bjtimeArr[1], bjtimeArr[2], bjtimeArr[3] , bjtimeArr[4], bjtimeArr[5]); } int main(void) { uint8_t bjtimeArr[6] = {22, 8, 18, 16, 6, 18}; // 1660809978 = 2022-08-18 16:06:18 BeijingTimeToUnix(bjtimeArr); while(1) { } }
-
3.3.2、运行结果
-