Unix时间戳
Unix时间戳简介
Unix时间戳,最早是在Unix系统使用的,所以叫Unix时间戳。之后很多由Unix演变而来的系统,也都继承了Unix时间戳的规定。目前,Linux、Windows、Android这些系统,它们底层的计时系统,都是使用的Unix时间戳。所以在我们现在计算机世界的底层,Unix时间戳还是在扮演着重要的角色。
-
Unix 时间戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒。
- 时间戳是一个计数器数值,这个数值表示的是一个从19709年1月1日0时0分0秒开始,到现在,总共所经过的秒数。时间戳定义1970年1月1日0点整,为0秒,之后,就只用最基本的秒来计时,永不进位,60秒就是60秒,100秒就是100秒,1千秒,1万秒,1亿秒,无论这个数有多大,我都不进位,始终都只用秒来计时。所以从1970年计到现在,这个时间戳的秒数已经到了16亿这个数量级。
- 时间戳的秒计数器和日期时间,可以相互转换。在计算机的底层,我们使用秒计数器来计时,需要具体时间时,就转换为年月日时分秒这样的格式就行了。
- 使用这样一个很大的秒数来表示时间,有很多好处
- 第一,简化硬件电路,在设计RTC硬件电路的时候,直接用一个很大的秒寄存器就可以了,不需要再考虑年月日寄存器、进位,大月小月、平年闰年这些东西了。
- 第二,在进行一些时间间隔的计算时,非常方便,比如1月1号8点到3月1号18点,之间间隔了多少小时,如果用年月日时分秒来计算,需要考虑的东西较多,但如果用秒计数器来计算,只需要把两个时刻的秒数相减,再除一个小时的秒数,就可以很快计算两个时刻的间隔了。
- 第三,存储方便,存储秒数,只需要一个比较大的变量就行了,存储年月日时分秒,就需要很多变量。
- 使用秒计数器来表示时间,比较占用软件资源,在每次进行秒计数器和日期时间转换时,软件都要进行一通比较复杂的计算,这会占用一些软件资源。
-
时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量。
- 在早期的Unix系统中,这个秒数大多使用32位有符号的整型变量来存储的,32位有符号数,所能表示的最大数字是,232/2-1,这个数是21亿多,是有溢出风险的,目前到2023年,时间戳已经计到16亿了,再过一些年,32位有符号数,就存不下这么大的数字了。根据计算,32位有符号数的时间戳,会在2038年的1月19号溢出。到时候,采用32位有符号数存储时间戳的设备,计时系统就会因为数据溢出而出错。这可能会导致很多不健全的计算机程序崩溃。
- 随着操作系统和设备的更新迭代, 目前的手机电脑等设备,基本上都已经采用64位的数据来存储时间戳了。64位的时间戳,能存储的时间范围非常非常的大,不用担心溢出风险。
- STM32F103C8T6中的RTC,核心部分是一个32位可编程计数器,说明它的时间戳是32位的数据类型,但是,这个STM32的时间戳,在程序中定义的其实是无符号的32位整形,无符号32位最大数值是232-1,计算可知,要到2106年才会溢出。
-
世界上所有时区的秒计数器相同,不同时区通过添加偏移来得到当地时间。
- 位于地球上不同经度,时间不同,穿过英国伦敦的经线,叫做本初子午线。这个位置的时间是一个时间标准,我们时间戳所说的1970年1月1日0时0分0秒,也是指的伦敦时间的0时0分0秒。其他地方,可以分为24个市区,每偏差一个时区,时间就要加或减一个小时,我们处理不同时区的方式是,所有时区共用一个时间戳的秒计数器,也就是,在伦敦秒计数器是0,在北京也是0,然后根据不同时区,我们再添加小时的偏移即可。比如秒计数器的0对应伦敦时间的0点,那中国,使用北京时间,处于东8区的位置,对应北京的时间就是8点。
UTC/GMT
-
GMT(Greenwich Mean Time)格林尼治标准时间 是一种以地球自转为基础的时间计量系统。它将地球自转一周的时间间隔等分为24小时,以此确定计时标准。(以前的时间标准)
- 地球自转一周的时间,其实是不固定的,由于潮汐力、地球活动等原因,地球目前是越转越慢的,如果再根据一天的时间来定义时间基准,这个时间基准就是在不断变化的。比如把一天等分为24小时对应的秒数,地球越转越慢,那定义1秒的时间,也就越来越长,一个不固定的时间基准,对科学研究影响非常大。
-
UTC(Universal Time Coordinated)协调世界时 是一种以原子钟为基础的时间计量系统。它规定铯133原子基态的两个超精细能级间在零磁场下跃迁辐射9,192,631,770周所持续的时间为1秒。当原子钟计时一天的时间与地球自转一周的时间相差超过0.9秒时,UTC会执行闰秒来保证其计时与地球自转的协调一致。(现行时间标准)
- 闰秒,就是计时标准是恒定不变的,但是地球越转越慢,误差超过0.9秒时,计时系统就多走一秒,来等一下地球的自转,比如上一次闰秒的时刻是北京时间2017年1月1日7时59分59秒,在下一秒时,时钟就会出现7时59分60秒,一分钟总共是61秒,这就是闰秒的操作。
- 恒定的时间标准加上闰秒的设计,就能保证UTC既满足科学研究的需要,又满足人类生活的需要。
时间戳转换
- C语言的time.h模块提供了时间获取和时间戳转换的相关函数,可以方便地进行秒计数器、日期时间和字符串之间的转换
函数 | 作用 |
---|---|
time_t time(time_t*); | 获取系统时钟 |
struct tm* gmtime(const time_t*); | 秒计数器转换为日期时间(格林尼治时间) |
struct tm* localtime(const time_t*); | 秒计数器转换为日期时间(当地时间) |
time_t mktime(struct tm*); | 日期时间转换为秒计数器(当地时间) |
char* ctime(const time_t*); | 秒计数器转换为字符串(默认格式) |
char* asctime(const struct tm*); | 日期时间转换为字符串(默认格式) |
size_t strftime(char*, size_t, const char*, const struct tm*); | 日期时间转换为字符串(自定义格式) |
![]() |