JustQyx

大道至简

Working With Timezone in Rails(03)

| Comments

前面两篇分别阐述了数据库对时区的不同处理处理方式和Rails中有关时区的两个选项设置。 这篇主要阐述在不同数据库对时区不同的支持情况下,Rails项目里改如何去选择时区。

不支持时区

这里说的 不支持时区 是指数据库表里的字段没有时区的概念,如 MySQL5.5 版本。

在这种情况下,如果项目使用人群是跨时区的,那么很明显地,在日期数据的存储和操作的过程中,我们都应该使用 UTC 时区,而日期数据的显示再根据本地的时区去显示。

如果项目的使用人群并不跨时区(或着相当长的一段时间内是确定不跨时区的),那么我们的选择就比较自由了。日期数据的存储和操作可以使用 UTC,也可以使用本地时区,而显示的时候,统一用本地时区去显示。 不过建议都统一采用本地时区,这样能避免在开发过程中出现的认为错误,如自己拼写SQL、使用AR但是非日期类型。

1
2
# 日期的存储采用了 UTC,并且字段不支持时区,但是拼写 SQL 时,以东八时区去做查询
User.connection.execute "SELECT * FROM users WHERE created_at >= '2014-05-18 08:00:00'"
1
2
3
4
# bad
User.where("users.created_at >= ?", '2014-05-18 00:00:00')
# good
User.where("users.created_at >= ?", Time.zone.parse('2014-05-18 00:00:00'))

支持时区

如果数据库的字段支持带数据,那么在建立的时候,建议都带上时区。 虽然会带上性能上的消耗,但是在数据库处理这个层面上处理保证不出错。

这样就简单了,如果项目的使用人群时跨时区的,那么在日期的处理和存储上都选用UTC,在显示时使用本地的时区去显示;如果项目的使用人群不跨时区,那么选用UTC和本地时区都可以(建议使用本地时区)。

双数据库

项目有时候会遇到要使用双数据库的情况,如数据平台,通常本身有会有数据库,而元数据则来自业务项目。 这种情况下,建议采用同一种数据库,即如果业务项目里使用的是 MySQL 那么就都用 MySQL, 对于时区的选择上也使用同一种时区方案。这样开发人员就不需要总是切换思维方式,能够避免许多错误。如果已有的项目选择的是不同的数据库并且还将继续开发维护相当长一段时间,那么建议尽早迁移成同样的数据库,毕竟后期的维护成本要高于迁移的成本。

总结

总的来说,对于日期的存储和处理上取决于项目的使用人群以及开发设计人员所选择的数据库,如果选择的数据库支持时区,那么建议创建表时相应的字段都带上时区,以避免日常的开发维护中由于人员可能引起的错误。而对于多数据库,建议尽量采用同种数据库,除非你喜欢折腾并且还能保证不出错。

Comments