UTC时间
UTC时间的英文全称:Universal Time Coordinated,中文名称:协调世界时。俗的理解为,这个时间是全世界通用的,即全世界都公用的一个时间。可以认为格林威治时间就是时间协调时间(GMT=UTC),格林威治时间和UTC时间均用秒数来计算的。
起始时间为:1970年1月1日

北京时间:UTC+8

本地时间
计算机显示的时间
本地时间 = UTC 时间 + 时区 (北京时间是东八区,也就是 +8小时)
UTC + 时区差 = 本地时间
时区差东为正,西为负。在此,把东八区时区差记为 +0800,

UNIX时间
在计算机中看到的UTC时间都是从(1970年01月01日 0:00:00)开始计算秒数的。所看到的UTC时间那就是从1970年这个时间点起到具体时间共有多少秒。 这个秒数就是Unix时间戳,与时区无关。应用于大多数Unix系统(linux,Ubuntu,ros)

考虑到闰秒的话,更精确的定义为从协调世界时(UTC时间)1970年1月1日0时0分0秒起至现在经过闰秒调整之后的总秒数。

所以Unix时间转换为本地时间,应该先将 Unix时间转换为UTC时间(UTC是0时区的时间),然后再将UTC时间转换为本地时间:

Unix时间戳转换为本地时间的在线工具

GPS时间系统
GPS使用UTC原子钟时间,起始时间为:1980年1月6日;

与unix两者相差:err=315964800秒GPS时间表示:周数Weeks和周内秒Secs,转成秒:sec = Weeks *7 * 24 * 3600 +Secs和ros的时间转为同一时间基准:s = sec + err - 闰秒次数即
unix_timestamp = gps_timestamp + 315964800 - LEAPSEC其中315964800 为两个时间起始相差的固定秒数
LEAPSEC :闰秒

GPS时间系统采用原子时AT1秒长作时间基准,秒长定义为铯原子CS133基态的两个超精细能级间跃迁辐射振荡9192631170周所持续的时间。

时间起算的原点定义在1980年1月6日世界协调时UTC0时,启动后不跳秒,保证时间的连续。以后随着时间积累,GPS时与UTC时的整秒差以及秒以下的差异通过时间服务部门定期公布。

GPS卫星广播星历采用WGS-84(G873)世界大地坐标系

闰秒
闰秒是在协调世界时(UTC)中增加或减少一秒,使得UTC时与原子时[5]之间的差不超过0.9秒。
需要闰秒的部分原因是因为一个太阳日并不总是86400秒。当要增加正闰秒时,这一秒是增加在第二天的00:00:00之前,效果是延缓UTC第二天的开始。当天23:59:59的下一秒被记为23:59:60,然后才是第二天的00:00:00。如果是负闰秒的话,23:59:58的下一秒就是第二天的00:00:00了,但目前还没有负闰秒调整的需求。
最近的一次添加闰秒是在2016年12月31日23:59:60。

闰秒是对“协调世界时”(UTC)所做出的基本调整,以便令其与太阳时间保持同步。

2016年7月6日,法国国际地球自转组织发布公告:国际标准时间将在格林尼治时间2016年12月31日23时59分59秒实施一个正闰秒,即增加1秒,届时将出现59分60秒的特殊现象。由于北京处于东8区,所以中国将在2017年1月1日7:59:59后面增加1秒,出现7:59:60的特殊现象。2016年最后一天,全球多一秒!

一般来说,闰秒会被添加在某一年的6月30日或者12月31日。两次闰秒之间的时间间隔并不固定,最短的一次只隔了6个月,最长的一次隔了7年。多出来的一秒对于普通人的生活或许没有太多影响,但是对于时间连续精度有严格要求的航天、通讯、金融等领域有很大影响。比如一秒钟,飞船已经飞过了8公里!

本次闰秒调整后UTC时间与GPS时间的差将变为18秒,即UTC相对于GPS时慢了18秒

UTC时间转UNIX时间戳

UTC时间转换成UNIX时间戳的方法其实很简单,因为此条件下输入的年月日是固定的。因此对于这个问题, 我们可以直接按照年月日时分的形式进行计算, 统计每它们的秒数之和。最后加入最后的秒数就可以得到当前的UNIX 时间戳了。我们知道闰年的秒数为31622400s,平年的秒数为31536000s。

程序的设计思路为:
1) 统计从1970年至今一共过了多少平年,多少闰年,统计完成之后,根据闰年和平年的秒数计算出从1970年1月1日至今年一共经过了多少秒。
2) 计算出当前年份是平年还是闰年, 以此推算出从年初到上个月过去了多少天。计算完成之后,可以将本月的到昨天的天数一起统计进来,最终可以将年月日三个单位的秒数一起统计出来。
3) 将剩余的时分秒利用同样的方式进行累加,最终得出当前的UNIX时间戳。

具体代码如下:

#include <stdio.h>
#include "timex_test1.h"
time_tt stCurrentTime; int main(void)
{stCurrentTime.year = 2023;stCurrentTime.month = 4;stCurrentTime.date = 13;stCurrentTime.hour = 9;stCurrentTime.minute = 30;stCurrentTime.second = 3;printf("%ds", UTCToUnixTimeStamp(&stCurrentTime));return 0;
}UnixTimeStamp_t UTCToUnixTimeStamp(time_tt *time)
{int FlatYearMonthDay[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int LeapYearMonthDay[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};time_tt *tempTime; //定义临时变量存储时间int i;tempTime = time; //指向传入参数int LeapYearNumber;     //闰年int FlatYearNumber; //平年int ThisYear;int LastMonDays = 0;UnixTimeStamp_t TimeStamp = 0;/*step1: 统计从1970年至今年,一共包含多少平年和闰年,并且计算其总秒数*/
for ( i = UNIX_TIME_STAMP_YEAR; i < tempTime->year; i ++ )
{if((((i % 4) == 0) && ((i % 100) != 0)) || ((i % 400) == 0)){LeapYearNumber ++;}else{FlatYearNumber ++;}
}
TimeStamp = LeapYearNumber * 31622400 + FlatYearNumber * 31536000;/*step2: 判断今年是平年还是闰年*/
if((((tempTime->year % 4) == 0) && ((tempTime->year % 100) != 0)) || ((tempTime->year % 400) ==0))
{ThisYear = LEAP_YEAR;
}
else
{ThisYear = FLAT_YEAR;
}for ( i = 1; i < tempTime->month; i ++)
{if(ThisYear == LEAP_YEAR){LastMonDays += LeapYearMonthDay[i];}else if(ThisYear == FLAT_YEAR){LastMonDays += FlatYearMonthDay[i];}
}
LastMonDays = LastMonDays + tempTime->date - 1; //统计当月到昨天为止的天数TimeStamp += LastMonDays * 86400;/*step3. 计算出剩余的时分秒*/
TimeStamp += tempTime->hour * 3600;
TimeStamp += tempTime->minute * 60;
TimeStamp += tempTime->second;
return TimeStamp;
}

timex_test1.h

#ifndef   __TIMEX_TEST1_H_
#define   __TIMEX_TEST1_H_#define UNIX_TIME_STAMP_YEAR  1970
#define LEAP_YEAR             1
#define FLAT_YEAR             0
typedef struct timex_test1
{int year;int month; int date; int hour;int minute; int second;
} time_tt;typedef unsigned int UnixTimeStamp_t;
UnixTimeStamp_t UTCToUnixTimeStamp(time_tt *time);
#endif

UNIX时间转UTC时间戳
1)时分秒的转换
当UNIX时间戳的计数值小于86400(24h)的时候,我们很容易就能写出转换成UTC时间的程序, 因为小时数就是“UnixTimeStamp” 对3200 取模, 分数就是将不能凑满小时的“UnixTimeStamp” 对60 取模, 剩余不能凑满分数的“UnixTimeStamp” 即为当前时间的秒数。

2)年月日的转换
接下来,我们将要再对“日”的上一层单位进行讨论,即“月”数值,这也将是这个程序最为复杂的一部分内容。
这个复杂点主要体现在两个方面:
(1) 每个月的天数不等。众所周知,一年中每个月的天数都是不同的,1,3,5,7,8, 10,12为大月,一个月有31天;4,6,9,11为小月,一个月有30天。
(2) 闰年平年的影响。由于公历的偏差,导致了一年中最为特殊的一个月份2月,当此年为闰年时,2月份有29天,此年为平年时,2月份有28天。
上面两个原因,导致了年月日计算的复杂性。

但是,困难只是表面上的,我们仔细思考下,就很容易得出规律。这个规律的突破口即为闰年出现的时间, 因为闰年每四年出现一次, 那么我们可以列出从1970 年开始的几个年份。如下图所示:


由于闰年每四年出现一次,因此我们由图3中可以得出一个简单方法,即可以从1790年开始,每四年组成一个集合,每一个集合的都是由1年闰年加上3年平年组成的,它们的时间都是相等的,即126230400秒。

因此这个月数的求解步骤就可以变为:
(1) 计算从1970 年开始到当前的UNIX时间戳为止, 一共过了多少个“ 集合年( 平年+ 闰年)”;
(2) 计算出当前的UNIX时间戳位于本“集合年“的哪一年,这样就可以判断当年年份是平年
还是闰年;
(3) 判断了当前年份是平年还是闰年之后,就可以推算出2月份有多少天,然后可以根据上述的递归法,求解出当前位于某一月,某一天。

所以,我们先求出当前的年份,得出当前年份之后, 我们就可以很容易使用“ 能被4 整除且不能被100 整除, 或者能被400 整除的年份是闰年”这一条规则算出当年年份是闰年还是平年。接着, 我们可以直接将当前年份剩余的时间戳结合平年还是闰年, 查表计算出当前的月份。

#include <stdio.h>
#include "timex_test2.h"
utc_t UtcTime;
int main(void)
{int retVal;int u32UnixTimeStamp = 0; int hour, minute, sec;int flat_year_month_day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int leap_year_month_day[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int year_temp = 0; int day_temp = 0;unsigned int cnt_temp = 0; int is_leap_or_flat_year; int i;printf("input the UNIX time stamp:"); scanf("%d", &u32UnixTimeStamp);cnt_temp = u32UnixTimeStamp;
/*判断当前UNIX时间戳经过了多少个4年*/ while(cnt_temp >= 126230400){year_temp ++;cnt_temp = cnt_temp - 126230400;}/*计算出当前的4年周期起始年份*/UtcTime.year = UNIX_TIME_YEAR + (4 * year_temp);/*计算出当前的年份*//*这部分代码可使用循环做精简,为了直观,我将其写开*/if(cnt_temp >= 31536000){UtcTime.year ++;cnt_temp -= 31536000;/*Flat year*/if(cnt_temp >= 31536000){UtcTime.year ++;cnt_temp -= 31536000;/*Leap year*/if(cnt_temp >= 31622400){UtcTime.year ++;cnt_temp -= 31622400;/*Flat year*/if(cnt_temp >= 31536000){UtcTime.year ++;cnt_temp -= 31536000;}}}/*计算当前年份是平年还是闰年*/
if((((UtcTime.year % 4) == 0) && ((UtcTime.year % 100) != 0)) || ((UtcTime.year % 4) ==0))
{is_leap_or_flat_year = LEAP_YEAR;
}
else
{is_leap_or_flat_year = FLAT_YEAR;
}
/*计算出不足一年剩余的天数*/
day_temp = cnt_temp / 86400;/*剩余不足86400s的时间戳,计算出时间*/
UtcTime.hour = (cnt_temp - day_temp * 86400) / 3600;   //Calculate hours
UtcTime.minute = (cnt_temp - day_temp * 86400 - UtcTime.hour * 3600) / 60; //Calculate minutes
UtcTime.second = cnt_temp % 60;/*将天数结合平年还是闰年查表计算出当前的月份*/
if(is_leap_or_flat_year == FLAT_YEAR)
{if(day_temp >= flat_year_month_day[i + 1]){UtcTime.month ++;day_temp -= flat_year_month_day[i + 1];}
}
else if(is_leap_or_flat_year == LEAP_YEAR)
{if(day_temp >= leap_year_month_day[i + 1]){UtcTime.month ++;day_temp -= leap_year_month_day[i + 1];}
}
}/*由于天数从1开始,因此需要加1*/
UtcTime.date = day_temp + 1;
printf("\nTime transform successfully\n");
printf("++++++++++++++++++++++++++++++++++\n");
printf("\nUTC time is : %dy - %dm - %dd\n", UtcTime.year, UtcTime.month, UtcTime.date);
printf("\nUTC time is : %dh - %dm : %ds\n", UtcTime.hour, UtcTime.minute, UtcTime.second);
printf("++++++++++++++++++++++++++++++++++\n");
printf("\n");
printf("\n");
return 0;
}

timex_test2.h

#ifndef   __TIMEX_H_
#define   __TIMEX_H_/*定义UTC时间结构体类型*/
typedef struct
{int year;
int month;
int date;
int hour;
int minute;
int second;
} utc_t;/*定义UNIX时间戳的起始UNIX时间*/
#define UNIX_TIME_YEAR  1970
#define UNIX_TIME_MONTH 1
#define UNIX_TIME_DATE  1
#define UNIX_TIME_HOUR  0
#define UNIX_TIME_MINIUTE   0
#define UNIX_TIME_SECOND    0
#define LEAP_YEAR   1
#define FLAT_YEAR#endif

Unix、UTC、GPS时间戳及转换相关推荐

  1. Unix时间戳,GPS时间戳 ,UTC时间 , 本地时间

    本地时间 : 计算机显示的时间 本地时间 = UTC 时间 + 时区 (北京时间是东八区,也就是 +8小时) unix 时间戳 : UTC时间都是从(1970年01月01日 0:00:00)开始计算秒 ...

  2. java unix时间戳转换_unix时间戳的转换 Java实现【附代码】

    今天爱分享给大家带来unix时间戳的转换 Java实现[附代码],希望能够帮助到大家. Java时间转换成unix时间戳的方法 Java进行时间转换成unix timestamp的具体代码,供大家参考 ...

  3. android utc时间转换,android 获取UTC时间和与.net时间戳的转换

    本文纯属整合,将在项目中用到的UTC时间和与.NET时间戳的转换进行记录.1.android获取UTC时间/***获取UTC时间**@return*/publicstaticStringgetUTCT ...

  4. JavaScript 时间与Unix时间戳互相转换,指定时间转换或获取当前时间

    工作上用到这个还挺多的,做个简单的随笔,以后查询的时候比较方便: 一般JS获取的时间戳默认是13位数字,在个人的工作中,PHP后台只需要精确到秒就行,看各位亲的需要了, 代码注释里尽量写的比较清楚了 ...

  5. Unix/Linux编程:时间转换

    unix time stamp翻译为时间戳, 就是从1970年1月1日00:00::00以来的秒数. 程序可能会关注两种类型的时间 真实时间.度量这一时间的起点有二: 其一为某个标准点. 也叫做日历时 ...

  6. Python 日期和时间戳的转换

    Python 日期和时间戳的转换 1. Python中处理时间的模块 Python中处理时间的模块有time.datetime和calendar. 在Python中表示时间的方式: 时间戳:10位整数 ...

  7. 在线时间戳格式化转换工具

    在线时间戳格式化转换工具 在线时间戳格式化转换工具 本工具支持在时间和时间戳之间相互转换,默认时间参考的是服务器时间 Unix时间戳(Unix timestamp),或称Unix时间(Unix tim ...

  8. 时间与时间戳如何转换

    时间与时间戳的转换(Python) 首先,什么是时间戳? 时间戳是指格林威治时间自1970年1月1日(00:00:00 GMT)至当前时间的总秒数.它也被称为Unix时间戳(Unix Timestam ...

  9. SLAM精度评估常见问题——GPS时间戳与bag包时间戳如何对齐

    在使用evo进行精度评估时,由于evo是通过时间戳来进行配准和比较的,为了使结果更准确,需要将GPS与bag包的时间戳进行转换对齐 在这里更方便的方法是转换GPS时间戳到bag包 首先查看GPS文件 ...

最新文章

  1. java 自定义http头_HttpClient自定义HTTP头
  2. 在 C/C++ 中使用 TensorFlow 预训练好的模型—— 直接调用 C++ 接口实现
  3. SAP UI5 click list item to navigate to detail page
  4. 2011(信息学奥赛一本通-T1234)
  5. bool转nsnumber ios_iOS开发之NSDecimalNumber的使用,货币计算/精确数值计算/保留位数等...
  6. 【IDEA】向IntelliJ IDEA创建的项目导入Jar包的两种方式
  7. 财务分析思维导图模板分享
  8. 美赛O奖、F奖论文写作技巧!【微信公众号:校园数模】
  9. Stream.sorted
  10. Codeforces Round 1299 简要题解
  11. pandas to_excel产生空值的解决方案
  12. 闲鱼选品的6个维度,附赠35个爆款品类!
  13. Python自动化开发学习14-html和css
  14. html 两个input挨着,欧洲区预选赛直播 -官方网站
  15. 关于请设置注册表项Framewoke.....初始化错误的解决办法
  16. 守护线程setDaemon的理解
  17. 永远不要和沙雕一样的人去争论,争论最后你会发现你也是一个沙雕
  18. 周杰伦一发新歌,服务器为什就挂掉了?
  19. matlab机械臂运动仿真
  20. C语言-实现栈(stack)

热门文章

  1. nCode:DesignLife案例教程九
  2. nCode:DesignLife案例教程十六
  3. 三维实景业务中的前端技术
  4. || ?? 和 ?. 的意思
  5. loawan-node 的SX1276GetPaSelect
  6. C语言字符串、宏定义及主函数介绍
  7. CCF推荐|JCR4区通信网络类SCI,仅1-2个月左右录用~
  8. postman 设置请求编码_Postman教程——细说请求
  9. 用 matplotlib 自定义添加 “哆啦A梦”背景图
  10. Python中用turtle库画哆啦A梦