资讯专栏INFORMATION COLUMN

日期居然用字符串保存?我笑了

Leck1e / 3452人阅读

摘要:微信公众号后端进阶,专注后端技术分享框架分布式中间件服务治理等等。

微信公众号「后端进阶」,专注后端技术分享:Java、Golang、WEB框架、分布式中间件、服务治理等等。  
老司机倾囊相授,带你一路进阶,来不及解释了快上车!

我发现数据库有些日期居然用字符串保存?于是跟几个小伙伴讨论了关于数据库的日期应该要怎么保存的问题,其实我一直都建议直接用数值保存时间戳,为什么我要这么建议呢?

以下,我会从时区的概念来跟你们解释一下,为什么用数值保存时间戳是最好的方案,同时也为了分享出来,让更多开发小伙伴留意这些细节性的东西。

相信时区对于很多人来说的很熟悉,因为地球是圆的,在地球上不同角落看到的太阳上升的角度都是不同的,即每个人对于时间的显示都是不一样的,

举个例子:

此时处于东 8 区的我们北京时间是 10 点,那么处于东 1 区的时间就是 3 点,但是他们的时间是等价的:

"2019-06-20 10:00 +8:00" = "2019-06-20 3:00 +1:00"

所以说,对于不同时区的人来说,显示的时间是不一样的,那么此时你是如何将将时间保存到数据中的呢?

我姑且假设你用的是 new Date() 方法来保存当时日期,但据我所知道的,数据库的 DateTime 类型是没有时区信息的,如果你此时用 DateTime 格式保存日期,就会丢失时区信息,如果你的服务器更该地址,从数据库读出来的日期数据就是错误的!

可能你会说,那我用 timeStamp 类型保存总不会丢失时区信息了吧?确实没丢失,没毛病。但是据我所知道的,timeStamp 保存的时间最长不能超过 2037 年,而且你要考虑每个数据的 timeStamp 类型都有可能不一样。

至于用字符串来存储时间,就更加不推荐了,姑且不从时区来说,你比较日期大小也是个问题,我举个例子:

to_char(SYSDATE, "yyyy-MM-dd") > START_TIME

要比较一个时间大小,我需要这么做,还需要将系统时间转成字符串来给你对比,而且在转换成字符串比较时,数据库内部也会将其转换成时间来比较,你觉得这种查询条件会好到哪里去?

我们也知道在 JDK8 中新的时间 API LocalDateTime 中,有着丰富的时区转换的方法可用,但即便你说你精通 LocalDateTime 的各种花式用法,你也不得不面对繁杂的转换。

所以,我们需要一个拥有「绝对是时间」,来帮助我们记录日期,帮我们节省下转换的时间,这个「绝对时间」就是时间戳,时间戳的定义是从一个基准时间开始算起,这个基准时间是「1970-1-1 00:00:00 +0:00」,从这个时间开始,用整数表示,以秒计时,随着时间的流逝这个时间整数不断增加。这样一来,我只需要一个数值,就可以完美地表示时间了,而且这个数值是一个绝对数值,即无论的身处地球的任何角落,这个表示时间的时间戳,都是一样的,生成的数值都是一样的,并且没有时区的概念,所以在系统的中时间的传输中,都不需要进行额外的转换了,只有在显示给用户的时候,才转换为字符串格式的本地时间。

而且很重要的一点就是,在现有的编程语言中,都提供了方法来获取时间戳,这对于我们不同语言的项目交互来说,不要太方便!所以在这里我强烈建议前后端关于时间的交互,都用时间戳来交互。

这时,可能有同学又来杠一波,你用一个出数值来表示时间,我查数据库时,以我的眼力和口算,根本不知道时间是多少,我觉得这个根本不需要担心啊,你查数据库无非是查看需要的数据而已,你在 sql 里面对时间戳个时间转换函数就好了,比如:

from_unixtime(1561053690000)

如果你还要继续杠,说我就是要在数据库表中看到时间,我觉得如果你要这样,为什么还需要前端,直接拿数据库当前端展示就好了。

我总结一下数据库用数值保存时间戳的诸多好处:

在数据库中日期比较不要太方便,小学一年级就会的数学题,而且性能好;

数值对于任何系统交互来说都不存在障碍;

基于绝对时间的数值存储,不存在时区问题;

在交互过程中,摒弃没必要的重重转换,一个数字走天下,用户需要显示,前端只需要拿到时间戳显示正确的本地时间;

解决了由于各个数据库对于时间实现的不一样导致的问题,比如说 Mysql 的时间函数跟 Oracle 会有一些差别,假如你现在的 sql 有时间函数,换了数据库很可能就会出错。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/77894.html

相关文章

  • 程序员的快乐就是这么朴素无华且枯燥

    摘要:想象着你们给我拼命点赞的样子,是多么的滑稽,我笑了笑,哎,程序员的快乐,往往就这么朴实无华,且枯燥。哎,程序员的快乐,往往就这么朴实无华,且枯燥。想象着,我很快就能掌控这系统了,我笑了笑。经过我多层,一个功能就这么实现了。 前言 只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 我是一个程序员,...

    Flands 评论0 收藏0
  • 3纠结的刺:当专家还是管理者

    摘要:结了账,大盘鸡居然没吃完,打了包,开始摇摇晃晃的吹着晚风,边消化食儿边散步回家。工作已完成为目的,而非成果。有的父母离得远沟通的少,即使是观念不同,也可以不予理会。 showImg(https://segmentfault.com/img/bV1Dqu?w=3500&h=2079); 晚上,上完了线上课,忽然想起来还没吃饭,随手拿起桌子上的葡萄放在嘴里,边寻思着晚饭吃什么,边去洗脸让驱...

    aervon 评论0 收藏0
  • 3纠结的刺:当专家还是管理者

    摘要:结了账,大盘鸡居然没吃完,打了包,开始摇摇晃晃的吹着晚风,边消化食儿边散步回家。工作已完成为目的,而非成果。有的父母离得远沟通的少,即使是观念不同,也可以不予理会。 showImg(https://segmentfault.com/img/bV1Dqu?w=3500&h=2079); 晚上,上完了线上课,忽然想起来还没吃饭,随手拿起桌子上的葡萄放在嘴里,边寻思着晚饭吃什么,边去洗脸让驱...

    kyanag 评论0 收藏0
  • 2讲个笑话:我想找一份理想的工作

    摘要:工作已完成为目的,而非成果。个不符合自己内心的理想工作。上了楼,直接微信视频,确定了他在电脑前之后,我开始让他按照我的思路走写出你觉得这份工作的不足之处。 showImg(https://segmentfault.com/img/bV1DpL?w=3500&h=1405); 晚上,上完了线上课,忽然想起来还没吃饭,随手拿起桌子上的葡萄放在嘴里,边寻思着晚饭吃什么,边去洗脸让驱除一下上课...

    Miyang 评论0 收藏0

发表评论

0条评论

Leck1e

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<