Rails+MySQL开发中的时间问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

 

MySQL中的时区

显示时区信息

 
  1. mysql> show variables like '%time_zone%'; 
  2. +------------------+--------+ 
  3. | Variable_name    | Value  | 
  4. +------------------+--------+ 
  5. | system_time_zone | CST    | 
  6. | time_zone        | SYSTEM | 
  7. +------------------+--------+ 
  8. 2 rows in set (0.00 sec) 

 

设置时区信息

+8:00是中国所在的时区,东八区。

 
  1. mysql> set time_zone = '+8:00'
  2. Query OK, 0 rows affected (0.00 sec) 

 

Rails中的时区

rails默认就是写入utc时间,然后读取也是utc时间。

设置config.time_zone只能保证写入数据库的时间是local,就是保证创建对象的时候created_at和updated_at使用设置的本地时间。

但是读出来的时候还是有可能是utc时间,有可能需要在界面上转换的。

rails推荐使用utc时间,这样就统一了,只是在界面显示的时候格式化为本地时间。

 
  1. rake time:zones:all #查看所有时区 
  2. rake time:zones:local #查看本地时区 

 

默认情况

我们使用

 
  1. rails g scaffold post title:string content:string 

生成一个model之后,打开【db/migrate/201200_create_posts.rb】文件看到下面的内容。

 
  1. class CreatePosts < ActiveRecord::Migration 
  2.   def change 
  3.     create_table :posts do |t| 
  4.       t.string :title 
  5.       t.string :content 
  6.  
  7.       t.timestamps 
  8.     end 
  9.   end 
  10. end 

t.timestamps会帮我们在数据库中生成created_at和updated_at两个字段,这两个字段rails会自动赋值不用我们手动指定。

在界面上添加post之后,打开log/production.log文件,会看到下面的内容。

 
  1. INSERT INTO `posts` (`category_id`, `content`, `created_at`, `picture`, `published`, `title`, `updated_at`, `url`) VALUES (1, 'post100', '2012-11-01 05:13:45', NULL, 0, 'post100', '2012-11-01 05:13:45','post100') 

如果没有看到这条sql语句,那么就是在config/applicaiton.rb中添加

 
  1. config.log_level = debug 

debug的级别会在日志中记录每个sql,方便调试。在发布到生产环境之后,修改这个级别信息。

请注意created_at的值,明明是中国时间中午插入的记录,但是insert语句中的时间却是utc时间,落后八个小时,因为中国是东八区+8:00。

插入数据库的值自然也就是这个utc时间。

 

设置时区之后

解决这个问题可以在config/application.rb文件中添加下面的配置。

 
  1. config.active_record.default_timezone = :local 
  2. config.time_zone = 'Beijing' 

再次插入数据,打开log文件,就会发现时间变成了北京时间,插入数据库的也是北京时间。进入mysql -u root -p之后,查询的结果也是北京时间。

在view文件中使用

 
  1. <%= created_at %> 

显示的结果是

 
  1. 2012-11-01 13:39:26 +0800 

是没有问题的,但是多了时区+0800信息。

要是使用

 
  1. <%= post.updated_at.to_s(:db) %> 

显示的结果就是

 
  1. 2012-11-01 05:39:26 

没有了+0800,但是时间又变成了utc时间了。

使用

 
  1. <%= post.updated_at.localtime.to_s(:db) %>  

就变成

 
  1. 2012-11-01 13:39:26 

这下没有时区+0800信息,时间也是本地时间了。就是先转换为本地时间,然后在进行格式化。

 

 
  1. created_at.utc  #转换为utc时间
  2. created_at.localtime  #转换为local时间

 

 

还有就是在rails console中有一点特别。

 
  1. 1.9.3-p286 :013 > p=Post.last 
  2.   Post Load (0.3ms)  SELECT `posts`.* FROM `posts` ORDER BY `posts`.`id` DESC LIMIT 1 
  3.  => #<Post id: 67, title: "发郭德纲的法国队", content: "asdfasdf", created_at: "2012-11-01 05:39:26", updated_at: "2012-11-01 05:39:26", url: "df", category_id: 1, published: false, picture: nil>  
  4. 1.9.3-p286 :014 > p.created_at 
  5.  => Thu, 01 Nov 2012 13:39:26 CST +08:00  

大家注意到了吗,在p=Post.last之后查询的结果显示created_at的时间是utc时间,但是等你敲入p.created_at之后,显示的值就变成了本地时间。

 

总结

时区以及日期的格式化是每个程序员的必修课,就像字符串的各种处理一样重要,而且使用频率很高。

rails默认就是写入utc时间,然后读取也是utc时间。

设置config.time_zone只能保证写入数据库的时间是local,就是保证创建对象的时候created_at和updated_at使用设置的本地时间。

但是读出来的时候还是有可能是utc时间,有可能需要在界面上转换的。

rails推荐使用utc时间,这样就统一了,只是在界面显示的时候格式化为本地时间。

对于任何应用来说,遇到时区问题,都应该考虑语言本身和存储本身,甚至是操作系统本身的时区设置和一些默认值,这样才能最终较好的解决时区问题




本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/1046723,如需转载请自行联系原作者

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
SQL 关系型数据库 MySQL
【MySQL】根据binlog日志获取回滚sql的一个开发思路
【MySQL】根据binlog日志获取回滚sql的一个开发思路
|
9月前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
407 1
|
10月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。
|
11月前
|
SQL JavaScript 关系型数据库
node博客小项目:接口开发、连接mysql数据库
【10月更文挑战第14天】node博客小项目:接口开发、连接mysql数据库
|
11月前
|
SQL 关系型数据库 MySQL
PHP与MySQL协同工作的艺术:开发高效动态网站
在这个后端技术迅速迭代的时代,PHP和MySQL的组合仍然是创建动态网站和应用的主流选择之一。本文将带领读者深入理解PHP后端逻辑与MySQL数据库之间的协同工作方式,包括数据的检索、插入、更新和删除操作。文章将通过一系列实用的示例和最佳实践,揭示如何充分利用这两种技术的优势,构建高效、安全且易于维护的动态网站。
|
11月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
246 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
存储 SQL 运维
运维开发.MySQL.范式与反范式化
运维开发.MySQL.范式与反范式化
101 1
|
存储 关系型数据库 MySQL
MySQL数据库开发进阶:精通数据库表的创建与管理22
【7月更文挑战第22天】数据库的创建与删除,数据表的创建与管理
133 1
|
数据库
基于PHP+MYSQL开发制作的趣味测试网站源码
基于PHP+MYSQL开发制作的趣味测试网站源码。可在后台提前设置好缘分, 自己手动在数据库里修改数据,数据库里有就会优先查询数据库的信息, 没设置的话第一次查询缘分都是非常好的 95-99,第二次查就比较差 , 所以如果要你女朋友查询你的名字觉得很好 那就得是她第一反应是查和你的缘分, 如果查的是别人,那不好意思,第二个可能是你。
164 3
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
1341 0

推荐镜像

更多