在应用中用到了 UTC 时间戳与北京时间进行转换的需求,这里做一个记录,方便后面有需求时直接拿来用。
要求实现 UTC 时间戳和北京时间的互相转换,其中月份取值范围为 0~11 代表 1~12月。其他时间参数正常(年、日、时、分、秒)
可以使用 时间戳转换在线工具 来验证转换后的时间是否正确。
这里以 2023-10-30 18:42:00 这个时间为例,转换后的 UTC 秒数为 1698662520。
#include <stdio.h>
typedef struct {
int year; // 年份
int month; // 月份范围:0-11代表1-12月
int day; // 日
int hour; // 小时
int minute; // 分钟
int second; // 秒
} DateTime;
int IsLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
int DaysInMonth(int year, int month) {
int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month == 1 && IsLeapYear(year))
return 29;
else
return days[month];
}
int UTCSecondsToBeijing(DateTime* dt, int seconds) {
int offset = 8 * 3600; // 北京为东八区,相对于UTC的偏移量为8小时
int totalSeconds = seconds + offset;
dt->year = 1970;
dt->month = 0;
dt->day = 1;
dt->hour = 0;
dt->minute = 0;
dt->second = 0;
while (totalSeconds >= 86400) {
int daysInYear = IsLeapYear(dt->year) ? 366 : 365;
if (totalSeconds >= daysInYear * 86400) {
totalSeconds -= daysInYear * 86400;
dt->year++;
}
else {
int month = 0;
while (totalSeconds >= DaysInMonth(dt->year, month) * 86400) {
totalSeconds -= DaysInMonth(dt->year, month) * 86400;
month++;
}
dt->month = month;
dt->day = totalSeconds / 86400 + 1;
totalSeconds %= 86400;
dt->hour = totalSeconds / 3600;
dt->minute = (totalSeconds % 3600) / 60;
dt->second = totalSeconds % 60;
break;
}
}
return totalSeconds;
}
int BeijingTimeToUTCSeconds(const DateTime* dt) {
int totalSeconds = 0;
for (int year = 1970; year < dt->year; year++) {
totalSeconds += IsLeapYear(year) ? 366 * 86400 : 365 * 86400;
}
for (int month = 0; month < dt->month; month++) {
totalSeconds += DaysInMonth(dt->year, month) * 86400;
}
totalSeconds += (dt->day - 1) * 86400;
totalSeconds += dt->hour * 3600;
totalSeconds += dt->minute * 60;
totalSeconds += dt->second;
int offset = 8 * 3600; // 北京为东八区,相对于UTC的偏移量为8小时
totalSeconds -= offset;
return totalSeconds;
}
int main() {
// 示例:UTC秒数转换成北京时间
int utcSeconds = 1698662520; // 假设给定的UTC秒数
DateTime beijingTime;
int remainingSeconds = UTCSecondsToBeijing(&beijingTime, utcSeconds);
printf("UTC Seconds: %d\n", utcSeconds);
printf("Beijing Time: %04d-%02d-%02d %02d:%02d:%02d\n",
beijingTime.year, beijingTime.month + 1, beijingTime.day,
beijingTime.hour, beijingTime.minute, beijingTime.second);
printf("Remaining Seconds: %d\n\n", remainingSeconds);
// 示例:北京时间转换成UTC秒数
DateTime inputTime;
inputTime.year = 2023;
inputTime.month = 12 - 1; // 月份范围:0-11代表1-12月
inputTime.day = 30;
inputTime.hour = 18;
inputTime.minute = 42;
inputTime.second = 0;
int utcSecondsResult = BeijingTimeToUTCSeconds(&inputTime);
printf("Beijing Time: %04d-%02d-%02d %02d:%02d:%02d\n",
inputTime.year, inputTime.month + 1, inputTime.day,
inputTime.hour, inputTime.minute, inputTime.second);
printf("UTC Seconds: %d\n", utcSecondsResult);
return 0;
}
上述代码分为两个部分,一个是将 UTC 秒数转换为北京时间,另一个是将北京时间转换为 UTC 秒数。你可以根据需要使用其中的任一部分。示例中的北京时间转换成 UTC 秒数部分使用的北京时间为 2023年10月30日18时42分,
从结果可以看到将 UTC 秒数转换成北京时间,以及从北京时间转换成 UTC 秒数无误。