数据库存储时间的时区问题-阿里云开发者社区

开发者社区> 熊哥club> 正文

数据库存储时间的时区问题

简介: 先说一下mysql中DATETIME和TIMESTAMP的区别 TIMESTAMP是标准的unix timestamp,它存储的是1970-1-1到现在经过的秒数,4字节存储。mysql用这个类型还蛮方便的,一个是有很多内置的函数和trigger来处理它,比如CURRENT_TIMESTAMP宏,最关键的是在取数据的时候mysql会自动帮你处理DST和时区的问题。 DATETIME的范围更
+关注继续查看
先说一下mysql中DATETIME和TIMESTAMP的区别

TIMESTAMP是标准的unix timestamp,它存储的是1970-1-1到现在经过的秒数,4字节存储。mysql用这个类型还蛮方便的,一个是有很多内置的函数和trigger来处理它,比如CURRENT_TIMESTAMP宏,最关键的是在取数据的时候mysql会自动帮你处理DST和时区的问题。

DATETIME的范围更大,好像可以从0000-00-00 00:00:00到9999-12-31 23:59:59,8字节存储,当然mysql内部肯定也是用整数而不是字符串的(说了是8字节了),所以效率不是大问题。但DATETIME不带时区,比如我在程序里生成了一个2015-05-07 15:26:00的时间(实际上是+8时区的,但这个对象可能是timezone naive)的,存到mysql里,再从不同时区的地方拿出来,这个时间可能就混了。

但TIMESTAMP也有两个很大的问题:

  1. 4字节长度限制,它只能到2038年
  2. 很多时候我们希望根据用户所在地的时区显示时间而不是光显示一个服务器时间

所以比较好的做法是,数据库中使用DATETIME,然后存时间的时候一律用程序生成UTC时间(而不是local时区的时间)存进去,取出来的时候不管想显示服务器时间还是显示用户的时间都可以处理。

顺便提一句,根据用户所在地时区显示时间有两种做法:

  1. 当用户第一次访问网站的时候,用js获取时区发送到服务器上存到session里
  2. 用js处理时间的显示(我觉得这种比较方便一点,毕竟不用改服务端代码)

使用这种做法的唯一缺点是sqlite3没有internal的DATETIME类型,所以在ORM框架如sqlalchemy中,它会直接存字符串进去。(sqlite3的文档也说,你要么存成int要么real要么字符串)。尽管这可能带来一些不方便和性能的下降,但我认为还是符合“keep it simple and stupid”的原则。

至于用INT存时间,是另一种可行的方法,参见http://www.liaoxuefeng.com/article/0014132675721847f569c3514034f099477...
我个人不是很喜欢这么做,因为这样你必须把模型中表示时间的成员声明为int类型。这样是比较不符合逻辑的(那些Date呀Datetime之类的类就没有用了呀,最多就有个Dateutil就好了),而且会使得程序不易读(卧槽这个publishedDate为什么是int,它到底表示的是时间吗?)。总之见仁见智。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
[20140804] 疑似存储上线导致数据库一致性问题
背景:       同一个存储设备提供了2块存储,1块已经在使用 a,另外一块没有使用b。 疑似:       当b初始化,上线之后,导致在a存储的数据库文件出现一致性问题。 原理:   具体原理目前不清楚,也是第一次碰到(看到文章的各位以后务必小心) 解决方法:       幸好有数据库镜像,打算切换数据库镜像,然后备份数据库镜像,还原到原来的master。
422 0
云时代下的数据库存储——运筹帷幄的阿里云数据库MongoDB
2018年1月17-25日,NoSQL数据库直播大讲堂峰会顺利结束,阿里云数据库团队为大家带来了一场别开生面的知识盛会,给大家带来深度的数据库技术及产品分享。本文是《ApsaraDB for MongoDB》演讲整理,主要讲解了阿里云数据库MongoDB全面的产品体系介绍以及阿里云数据库MongoDB在备份、监控、安全等方面所做的一些优化细节的具体剖析。
6673 0
数据库5.7 日期有时间类型
简介 日期与时间类型 mysql中有多种表示日期的数据类型,主要有:DATETIME DATE TIMESTAMP,DATE .每一个类型都有合法的取值范围,当指定确实不合法的值时系统将“零”值插入到数据库中。
585 0
数据库存储时间的时区问题
先说一下mysql中DATETIME和TIMESTAMP的区别 TIMESTAMP是标准的unix timestamp,它存储的是1970-1-1到现在经过的秒数,4字节存储。mysql用这个类型还蛮方便的,一个是有很多内置的函数和trigger来处理它,比如CURRENT_TIMESTAMP宏,最关键的是在取数据的时候mysql会自动帮你处理DST和时区的问题。 DATETIME的范围更
1827 0
数据库存储图像及使用Image控件显示
在数据库中存取并显示到页面Image控件的功能。原来认为并不复杂,但是实际中却遇到了一些问题。 首先来看看保存图片: 图片在数据库中使用二进制方式存储,所以要把图片转化为二进制流文件在存储到数据库中,代码如下:     private void Save()     {         MyImage img = new MyImage();         img.
672 0
+关注
熊哥club
java,前端相关专家
68
文章
4
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载