这期次要来聊一下 MongoDB 中的时区问题。
这个问题尽管简略,总有同学会问到,集中解答一下。
提出这个问题通常是因为在应用 Mongo Shell 后发现其中展现的工夫比中国工夫落后 8 小时而产生的。
比方:插入工夫是 2021 年 1 月 1 日 00:00:00,在 Shell 中看到的则是 ISODate(“2020-12-31T16:00:00Z”),很多人由此产生纳闷,8 小时去哪了?是不是出错了?
了解这个问题首先要了解时区的概念。当你同时向一个身处中国的人和身处美国的人发问当初是几点时,中国人答复中午 12 点,美国人答复的却是凌晨 4 点。这有区别吗?他们说错了吗?他们都没错。他们答复不一样是因为身处不同的时区,然而他们指代的都是同一个工夫:当初。
也能够说,全世界只有一个工夫,只是大家形容它的形式不一样——依据本人身处的地区。而有个现状会把这个问题搞得更简单,那就是夏令时。
我国当初曾经不施行夏令时了(对,过来有过!裸露年龄!),然而世界上有很多国家依然保留夏令时的习惯。这让本来简单的工夫表白更加雪上加霜。这在施行同样的工夫规定的人之间不会造成问题。
然而在国际化的明天,你晓得一个中国人跟一个施行了夏令时的德国人约一个会议工夫有多难?或者在看到一个德国工夫 2020 年 5 月 7 日 18 点,你晓得它是英国工夫的几点吗?你不光要晓得英德的时差,还要晓得 2020 年 5 月 7 日这个工夫在德国是不是在夏令时的影响范畴内,以及在英国它是不是在夏令时的影响范畴内。当初有没有感觉小瞧了工夫的复杂性?
为了简化这些简单的问题,有了 UTC (Universal Time Coordinated) 工夫规范以及表白工夫的规范 ISO 8601,也就是咱们在 MongoDB 中看到的 ISODate。
ISODate 的示意办法简略来说就是年月日时分秒 + 时区。以咱们后面的例子来说,身处中国时咱们的时区是 UTC+8,用 ISODate 表白则是 ISODate(“2021-01-01T00:00:00+0800”)。这个工夫在 MongoDB 中的表白是 ISODate(“2020-12-31T16:00:00Z”),其中的 Z 示意 UTC(或者 UTC+0)。因为时区的不同导致了表达方式不同,但这两个工夫指代的是同一时刻,所以两者没有什么不一样。而在展现时,则应该依据你的用户所处的时区来决定到底显示哪一个后果。
须要留神的是:有些语言的驱动(例如 Java/C#)在读取到工夫时会主动转换为服务器工夫,所以不须要再人为转换。有些语言(例如 Python)则不会主动转换。应用时应该依据你的理论状况决定解决形式。
作者介绍:张耀星
MongoDB 大中华区首席征询参谋,供职于 MongoDB 售后服务团队 5 年 +,领有近 10 年 MongoDB 应用教训。