编辑
2023-09-18
技术
00
请注意,本文编写于 492 天前,最后修改于 170 天前,其中某些信息可能已经过时。

一个两三年前的项目被告知出现了一个问题,所有的日期都是错的,和实际时间相差了八个小时
因为历史久远+之前的同事离职+这部分我从来没接触过,当时就感觉有一点点头大
排查结果发现最初的数据库数据是正确的,最终的业务端代码获取到时间也没有额外进行处理
整体的处理流程大概是这样的

A数据存入数据库 ---> B定时脚本获取数据库数据,并推送到ES ---> C业务端搜索es获取数据并展示
流程很简单,补充一些细节
A步骤数据库是SQLserver(以前没用过,在navicat里面配置的格式居然是[ip,port],是逗号而不是冒号,离谱),对应字段的存储格式是datetime
B步骤在进行推送的时候将获取到的datetime转换成了timestamp,之后推送到了ES
C步骤直接用ES获取了datetime,也就是说es自动将获取到的timestamp转换成了datetime
因为是相差八个小时,所以第一反应还是可能是由于时区的影响,之前没有了解过相关情况于是去搜索了一下

timestamp没有时区概念,其实以UTC格式存储的,UTC 是现在全球通用的时间标准,全球各地都同意将各自的时间进行同步协调。UTC 时间是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以秒为单位的国际原子时所综合精算而成。
额外的概念包括
GMT(Greenwich Mean Time), 格林威治平时(也称格林威治时间)。它规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午12点。
GMT是前世界标准时,UTC是现世界标准时。UTC 比 GMT更精准,以原子时计时,适应现代社会的精确计时。但在不需要精确到秒的情况下,二者可以视为等同。每年格林尼治天文台会发调时信息,基于UTC。参考https://zhuanlan.zhihu.com/p/135951778
而datetime是基于本地时区的日常使用日期时间,众所周知出国大概率可能会有时差,也就是说北京时间的上午八点和纽约时间的上午八点必然不是一个时间点,所以如果使用datetime跨时差,则会出现问题,该项目的日期问题也是由于此。

SQLserver,同步脚本服务器,业务服务器都是基于GMT+8的东八区;而ES所在的服务器则是使用GMT+0时间。
因此在B步骤中,正确的时间被ES进行了存储为了GMT+0的datetime,而在C步骤中,GMT+8的服务器获取到了GMT+0服务器的datetime时间,导致两者之间实际相差了8h。

最终的解决,实际上还是偷懒了,因为ES服务器历史比较久远,不想去动他,也不想重启任何服务,所以直接基于业务服务器,将datetime向后推迟了8h,从而使得业务端的搜索结果时间正常显示。

本文作者:康恩

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 Copyright © 2024 KangEn 许可协议。转载请注明出处!