标题: [算法原理解析] 纯手工将Unix时间戳转换为日期
时间: 2020-12-30发布,2020-12-30修改
实际开发中不需要使用手写的算法,调用系统提供的函数就能把时间戳转换为具体日期时间了。下面描述的方法只是让你对具体转换过程有更清楚的认识而已。
Unix时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。
所以只要有公历历法知识,知道每年有多少个月,每个月有多少天,就可以计算出日期了。
至于时间,对86400(一天的秒数)取模后剩下的值就是一天内经过的秒数,整除3600得到小时,对3600取模再整除60得到分,对60取模得到秒。
以“北京时间 2020-12-30 15:48:13”为例:
时间戳 = 1609314493
一天内经过的秒数 = 时间戳 % 86400 = 1609314493 % 86400 = 28093
小时 = 一天内经过的秒数 / 3600 = 28093 / 3600 = 7
分钟 = (一天内经过的秒数 % 3600) / 60 = (28093 % 3600) / 60 = 48
秒 = 一天内经过的秒数 % 60 = 28093 % 60 = 13
所以时间戳 1609314493
就是UTC时间 07:48:13
转换为北京时间,+8小时,得到 15:48:13
至于年月日,因为存在闰年闰月,稍微复杂一些。
经过的天数 = 时间戳 / 86400 = 1609314493 / 86400 = 18626
那么剩下的问题就是从1970年1月1日起再过18626天,是多少年几月几日?
18626 / 365 = 51
1970 + 51 = 2021
但实际上4年一闰,所以平均每年是365.25天。
floor(18626 / 365.25) = floor(50.99520876112252) = 50
1970 + 50 = 2020
年份就算出来了。
至于要计算月份和日期,就更困难一些,因为月份的天数是不等的,并且每年的2月天数也不完全相同,似乎不能使用除法直接给出解。
但如果我们把四年视为一个整体呢?这个整体一共有
365 * 3 + 366 = 1461 天
然后
18626 / 1461 * 4 = 12 * 4 = 48
18626 % 1461 = 1094
所以是从1970年1月1日后经过了12个4年,也就是48年,再加上1094天。
1970 + 48 = 2018
所以是2018年1月1日加上1094天。
2018年和2019年是平年,都只有365天:
1094 - 365 * 2 = 1094 - 730 = 364
所以是2020年1月1日加上364天。
2020年是闰年,共366天。1月1日加上364天就是365天,也就是倒数第二天。
所以是2020年12月30日。
编程实现的时候,只要把每月有多少天存在一个数组里,然后遍历递减到小于0就可以得到月和日了。注意2月可能是28天或者29天,需要根据算出的年是否为闰年判断。此外,能被100整除但不能被400整除的年不是闰年,需要记住这个例外。
『回复列表(9|隐藏机器人聊天)』
老虎怎么开始水这种帖子了?难道真的已经成为了底层程序员?
那你天天写底层代码,啥时候才能做到高层程序员?
顺便一提,完美严谨的闰年的判断很多人忽略了一些事情:
对于数值很大的年份,这年如果能整除3200,并且能整除172800则是闰年。如172800年是闰年,86400年不是闰年(因为虽然能整除3200,但不能整除172800)(此按一回归年365天5h48'45.5''计算)。
此外,如依照现有太阳年的长度与上述闰年规则,每8000年又约差一日,因此约翰·赫歇尔提议每逢4000的倍数不闰,如西元4000年。但距此一年份来临尚有约二千年之遥,因此还未曾真正纳入规则或实施过。又由于地球公转速率的不稳定与众多影响因素,届时是否需要纳入此规则仍有疑问。
小米MIX2s(白)