Skip to content

Latest commit

 

History

History
70 lines (42 loc) · 4.48 KB

时区问题.md

File metadata and controls

70 lines (42 loc) · 4.48 KB
created_at updated_at slug tags
2021-07-13 03:45:23 -0700
2021-07-13 03:47:55 -0700
time-zone-problem
时区

PostgreSQ中,timstamp是不带时区的类型,timestamp with zone是带时区的类型;函数CURRENT_TIMESTAMP得到的是timestamp with zone的当前时间;函数LOCALTIMESTAMP得到的是timestamp类型的时间。

那么你知道,将CURRENT_TIMESTAMP赋值给一个timstamp类型的字段会发生什么吗?

时区?偏移量?

在搞清楚数据库和代码中的时区表达之前,必须掌握好基础知识。

你能分清GMT、UTC、夏令时、时区等概念吗?

对于上面四个概念,下面这篇文章算是讲的比较清楚。

简单来说,GMT就是以前的时间标准,以格林威治的时间作为世界标准时间,其它各个时区以此为参考增加或减少小时数;UTC是新的世界时间标准,与GMT不同,GMT是单纯以格林威治这个地方作为标准时参考,UTC是结合了平均太阳时、地轴运动修正、国际原子钟综合得到的精确结果;夏令时,是指在天亮比较早的夏季人为将时间调早一个小时,我们对它不是很熟悉是因为我国1991年开始就已经废除了下令时;时区,理论来说,按照经度划分,每15度为一个时区,全球总共24个时区,每个时区相差一个小时,为啥是理论呢?这是因为实际还会考虑政治因素,很过国家一个国家跨多个时区,但他们都使用一个时区,所以时区不是严格按照经度划分的。

这篇文章可做参考

格林威治在哪里,看下面这张图。

格林威治时间.png

你能分清+08:00、Asia/Shanghai、GMT-这几种表达的区别吗?

Asia/Shanghai与GMT-8的区别

先说Asia/Shanghai,这是以地区命名的地区标准时,叫做CST;+8:00,指的是东八区。现在这个年份来说,二者表述一样,但是前者还包含一些历史时间,比如91年之前,我国实行过一段时间夏令时,如果将时区设置为Asia/Shanghai,那么在获取91年之前的时间时候就会有所差异。

其实地区标准时是非常有必要的,比如我们的日历中,使用地区标准是必须的,91年之前的时间你肯定想要显示当时的计算结果。

LocalDateTime/ZoneOffsetDateTime/ZonedDateTime

认识它们:

LocalDateTime、OffsetDateTime、ZonedDateTime互转,这一篇绝对喂饱你

ZoneOffset和Zoned的区别,通过解释Asia/Shanghai和+8:00的区别,想必已经了解了。

理解上述的几个关键点

  • LocalDateTime不带时区,不带时区不是说它的时间就是UTC时间,而是说它就是一个时间字面量,不能够标识时间线上的某个时间。核心是理解Local这个概念,即当地时间,“当地”,与时区无关。

    它不能表示时间线上的点,因此无法获取其epoch值,要获取时必须指定时区变成时间线上点才行。

  • ZoneOffsetDateTime,即以偏移量表示的时间。

  • ZonedDateTime,即以地区时间表示的时间,即我们常说的时区。

  • ZoneOffsetDateTime与ZonedDateTime区别

    • 前者可以自由设置偏移量,后者无法设置偏移量,只能根据时区来设置
    • 后者能够很好得支持夏令时,前者不行
  • 为什么它们之间能够相互转换?

    • LocalDateTime不能直接转换为其它两种类型,除非它指定是在哪个时区的本地时间。这也能够理解,本地时间+时区,不就成了通用时间了吗。
    • 偏移量和地区时间如何转换呢?前者转后者比较好做,因为时区包含了偏移量。

数据库应该使用带时区还是不带时区的类型?

当然是带时区的类型啦。

如果不带时区,是无法表示时间线上的某个点的;就会出现,如果数据库的时区设置在东八区,则生成的时间就是东八区的本地时间;如果设置在0时区,则生成的就是0时区的本地时间;二者是不一样的。也就是说,生成的时间在时间线上的位置会随着数据库时区的变化而变化,这显然是不合理的。

如果使用带时区的类型,只不过是在显示该日期时会有所差别,但实际上的时间是没有问题的。

其实,理论上最好的方式是存储epoch值,这样就不用管各种不同的数据库之间时间类型的差异了。