当前位置: 首页 > news >正文

UTC时间戳与北京时间转换

文章目录

  • 前言
  • 一、几个时间相关的概念
  • 二、场景
  • 三、验证方法
  • 四、源码
  • 五、运行结果
  • 六、资源自取


前言

在应用中用到了 UTC 时间戳与北京时间进行转换的需求,这里做一个记录,方便后面有需求时直接拿来用。


一、几个时间相关的概念

  • GMT 时间:Greenwich Mean Time,格林尼治平时,又称格林尼治平均时间或格林尼治标准时间。是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间。
    • GMT存在较大误差,因此现在已不再被作为标准时间使用。现在的标准时间,是由原子钟报时的协调世界时(UTC)
  • UTC 时间:Universal Time Coordinated,中文名称:世界标准时间或世界协调时。
    • UTC时间可以理解为全世界都公用的一个时间。它实际上反映了一种约定,即为全世界所认可的一个统一时间,而不是某特定地区的时间。
    • 中国人常用的北京时间比 UTC 时间快8个小时。也即 UTC 时间凌晨 0 点时,北京时间已经是早上 8 点,这就是为啥全世界人往往不直接用 UTC 时间计时原因。
  • CST 时间:China Standard Time,即中国标准时间。在时区划分上,属东八区,比协调世界时早8小时,记为UTC+8。
  • UNIX 时间戳(timestamp):计算机中的 UNIX 时间戳,是以 GMT/UTC 时间 1970-01-01 00:00:00 为起点,到当前具体时间的秒数(不考虑闰秒)。这样做的目的,主要是通过“整数计算”来简化计算机对时间操作的复杂度。

二、场景

要求实现 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;elsereturn 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 秒数无误。

六、资源自取

UTC时间戳与北京时间转换


我的qq:2442391036,欢迎交流!


相关文章:

  • Docker:CentOS7安装Docker
  • 一文详解汽车电子LIN总线
  • 递归神经网络 (RNN)
  • OpenGL_Learn02
  • Redis测试新手入门教程
  • SpringBoot2.7.14整合redis7
  • audio 标签动态src 且src是http无法播放问题
  • 数据结构单链表的实现(C语言)
  • 【kubernetes】Debian使用Kubeadm部署Kubernetes失败:Connection Refused
  • 【Linux】权限
  • 京东平台数据分析:2023年9月京东扫地机器人行业品牌销售排行榜
  • 039-第三代软件开发-PDF阅读器
  • 21.12 Python 实现网站服务器
  • Kali安装docker
  • ES6中的class类
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【附node操作实例】redis简明入门系列—字符串类型
  • docker python 配置
  • go append函数以及写入
  • Java 多线程编程之:notify 和 wait 用法
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • VuePress 静态网站生成
  • 大快搜索数据爬虫技术实例安装教学篇
  • 大主子表关联的性能优化方法
  • 解析 Webpack中import、require、按需加载的执行过程
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 问题之ssh中Host key verification failed的解决
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • Java数据解析之JSON
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • #{}和${}的区别是什么 -- java面试
  • #include
  • #Spring-boot高级
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (翻译)terry crowley: 写给程序员
  • (附源码)php投票系统 毕业设计 121500
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (三十五)大数据实战——Superset可视化平台搭建
  • (十三)Maven插件解析运行机制
  • (五)IO流之ByteArrayInput/OutputStream
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转载)Google Chrome调试JS
  • . NET自动找可写目录
  • .net core Swagger 过滤部分Api
  • .net 重复调用webservice_Java RMI 远程调用详解,优劣势说明
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • .net快速开发框架源码分享
  • .NET中使用Redis (二)
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示