转自 http://cao7113.blog.sohu.com/147243545.html
刚接触rails时,有时看到插入数据库的created_at字段与本地时间不一致,未深究。最近几个项目集成时,又遇相关问题,本文为调查记录,相关点:
本地时间-即观察者使用的当地时间(按地理标准时区概念)
操作系统时区设置
程序(Rails/Java)时区设置
数据库(MySql)时间字段的时区标准/设置
相关资料:
概念:
UTC-世界标准时间
LT-本地时间
CST-Central Standard Time, time zone offset: utc-6 hours
CST is used during winter in these US states(CDT during summer)...
计算机时间:主板上有个时钟发生器,用于计时。可通过CMOS设置时间(硬件时间)。Windows和Linux/Unix/Mac对硬件时间的理解不同,前者把它理解为LT(含时区值),后者理解为UTC,系统显示的时间是累加时区后的时间,网上很多人装双系统遇到时间不一致,就是这个原因。系统开机时读取硬件时间,关机时将对应值重新写入。
OS上的软件,一般都基于OS的时区设置,有些允许独立设置,如MySql,以支持世界各种时间变化,存储的时间字段也基于此时区设置。
Rails程序中的时区概念只是其间转换的工具(程序控制级别)
MySql:
MySQL 时区默认是服务器时区
可以通过以下命令查看
SQL代码
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)
可以通过修改my.cnf
在 [mysqld] 之下加
default-time-zone=timezone
来修改时区。如:
default-time-zone = '+8:00'
改了记得重启msyql喔!
另外也可以通过命令 set time_zone = timezone
比如北京时间(GMT+0800)
set time_zone = '+8:00';
Rails:
rails时区相关的rake tasks: time:zones:all/us/local
caoruijian@caoruijian-desktop:$ rake --tasks time:
(in /home/caoruijian/Aptana RadRails Workspace/web)
rake time:zones:all # Displays names of all time zones recognized by the Rails TimeZone class, grouped by offset.
rake time:zones:local # Displays names of time zones recognized by the Rails TimeZone class with the same offset as the system local time
rake time:zones:us # Displays names of US time zones recognized by the Rails TimeZone class, grouped by offset.
rails相关类:TimeZone(2.1版本后),timezone是rails2.1后新加的特征,并对ruby的Time做了扩展
Time.zone可以查看时区,Time.zone=可以设置
Time.now显示本地时区的时间值
项目可能遇到的一个问题是:在rails中看到的是本地时间(如北京时间),利用Model.create方式存入数据库(Mysql)后看到的是UTC时间(早八个小时),完成的一个测试实验如下:
环境:
OS: Ubuntu, Timezong: Shanghai(同Beijing,东8区)
Rails: environment.rb中设置config.time_zone = 'Beijing'#UTC
MySql: my.cnf中设置default-time-zone = '+8:00'(现在作用还不明)
操作:在rails的action中调用User.create往数据库表自动插入一条记录,现在为早上09:24左右(系统显示的本地时间),rails生成的Sql为:
Processing TestController#test (for 127.0.0.1 at 2010-03-31 09:24:20) [GET]
\u001B[4;36;1mUser Columns (0.6ms)\u001B[0m \u001B[0;1mSHOW FIELDS FROM `users`\u001B[0m
\u001B[4;35;1mSQL (0.0ms)\u001B[0m \u001B[0mBEGIN\u001B[0m
\u001B[4;36;1mUser Create (0.9ms)\u001B[0m \u001B[0;1mINSERT INTO `users` (`name`, `created_at`, `updated_at`) VALUES(NULL, '2010-03-31 01:24:20', '2010-03-31 01:24:20')\u001B[0m
\u001B[4;35;1mSQL (34.9ms)\u001B[0m \u001B[0mCOMMIT\u001B[0m.
可见,rails在往数据库发送数据前就做了某些转换,实验中将Beijing时区的时间转换为UTC的啦。可见问题出在rails的ActiveRecord的转换机制上,那究竟是怎么回事呢?网搜后看到有人设置了:
config.active_record.default_timezone = 'Beijing'#:local (environment.rb中)
呵呵,实验后果然看起来正常啦!问题应该是ActiveRecord默认使用UTC时区时间,默认会在你设置的时区和UTC间转换。由此更能体会到ActiveRecord作为程序和数据库间连接纽带的作用
源码解析:(rails-2.3.4/lib/initialize.rb Rails::Initializer#initialize_time_zone)
# Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes.
# If assigned value cannot be matched to a TimeZone, an exception will be raised.
def initialize_time_zone
if configuration.time_zone
zone_default = Time.__send__(:get_zone, configuration.time_zone)
unless zone_default
raise \
'Value assigned to config.time_zone not recognized.' +
'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
end
Time.zone_default = zone_default
if configuration.frameworks.include?(:active_record)
ActiveRecord::Base.time_zone_aware_attributes = true
ActiveRecord::Base.default_timezone = :utc #呵呵,找到啦!
end
end
end
那前文提到的MySql时区设置看起来为啥没起作用呢?问题还在于自己的理解上,default-time-zone = '+8:00',只在数据库级别上使用,并将任何输入作为该时区的时间值进行相关时间操作,跟这里要说的问题没什么关系
以上为临时记录,待进一步整理/更新,可能涉及的相关问题有:
* rails时间/时区机制与原理,当使用ActiveRecord时对数据库时间的影响?
* 当设定了某一时区时,对rails时间函数/时间比较逻辑的影响,如Time.now, Time.zone.now分别是那个时间?编写程序时是否要有时区意识,是否要修改遗留代码?
* 系统如何处理多时区/地区/语言问题,更复杂的设置?可能关系到服务器上程序的国际/区域化管理
分享到:
相关推荐
基于java的开发源码-Rails3消息队列系统 Sidekiq.zip 基于java的开发源码-Rails3消息队列系统 Sidekiq.zip 基于java的开发源码-Rails3消息队列系统 Sidekiq.zip 基于java的开发源码-Rails3消息队列系统 Sidekiq.zip ...
jquery-datatables-rails, 用于 Rails的jquery数据表 gem jquery-datatables-rails 这个 gem 为 jQuery DataTables插件提供了方便,以便与 Rails 资产pipleine结合使用。 它提供所有基本的datatable文件,以及一些...
Cucumber-Rails集成了Cucumber与Rails,使得开发者能够在Rails环境中方便地使用Cucumber进行功能测试。 在 Rails 应用中使用 Cucumber-Rails,开发者可以创建一个名为`features`的目录,里面包含这些Gherkin特性...
jquery-fileupload-rails, 用于 Rails的jQuery文件上传集成 Rails 文件上传jQuery-File-Plugin 是一个文件上传插件,由的Tschan 。 jQuery文件上传功能多文件选择。drag&拖放支持。进度栏和jQuery预览图像。 支持...
turbo-sprockets-rails3, 加速你的Rails 3资产 用于 Rails 3.2.x的涡轮链轮 通过只根据源文件的哈希来重新编译已经更改的资产,从而加快 Rails 3 rake assets:precompile的速度只编译一次以生成指纹和非打印的资产...
"Angle-3.4-rails"是一个专门针对Rails框架的项目,其包含了"backend-rails"和"backend-rails-seed"两个关键部分,旨在为开发者提供一个强大的后端开发环境和数据初始化工具。 一、Rails框架介绍 Rails是由David ...
projectile-rails, 基于弹丸的Rails 模式 弹 Rails 概要弹 Rails 是在 GNU Emacs中使用 Ruby on Rails 应用程序和引擎的次要模式。 在内部,它是基于弹 。这意味着你可以在 greping ( 或者 acking ) 文件。运行测试...
在这个案例中,我们看到`jquery-ui-rails-4.2.1.gem`,这是该gem的一个特定版本。这个gem负责将jQuery UI的库文件打包并整合到Rails的asset pipeline中,使得在Rails项目中使用jQuery UI变得简单。 要使用`jquery-...
《InfluxDB与Rails集成深度解析——以influxdb-rails源码为例》 InfluxDB,作为一款专为时间序列数据设计的高性能数据库,被广泛应用于监控、物联网、大数据分析等领域。Rails,作为Ruby on Rails框架的核心部分,...
webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成 不再维护webpack-rails 不再被维护。 有关详细信息,请参阅 #90. web pack-railsweb pack 为你提供了将 web pack集成到现有的Ruby on Rails 应用程序中...
grape-swagger-rails, Swagger UI作为葡萄 Swagger gem的Rails 引擎 GrapeSwaggerRails Swagger UI作为葡萄 Swagger gem的Rails 引擎。安装将此行添加到你的应用程序的Gemfile中:gem 'grape-swagger-rails'
Clojurescript的使用不仅限于Rails,它还可以与其他框架和库结合,如React、Ember等,提供了一种不同于JavaScript的开发体验。Clojurescript的函数式编程特性、宏系统和Lisp风格的语法,对于一些开发者来说,可能...
minitest-rails, Rails的Minitest集成 minitestRails 5的Minitest集成 安装gem install minitest-rails这将安装以下宝石:minitest配置创建一个新的Rail
这个简单的插件使您能够调用to_xls到Rails的数组集合。 数组元素支持对象:ActiveRecord,Mongid,哈希。 在您的Gemfile中: gem 'to_xls-rails' # Last officially released gem # gem "to_xls-rails", :git => ...
警告:此gem与3.0.0之前的jquery-rails gem不兼容! 如果您使用早期的jquery-rails版本,将会发生奇怪的事情。 运行bundle list ,以确保你要么不使用jquery-rails ,或者至少是3.0.0版本的jquery-rails 。 用法 在...
breach-mitigation-rails, 使 Rails 应用程序更能抵御入侵和犯罪攻击 breach-mitigation-rails使 Rails 3和 4应用程序 LESS 容易受到入侵/犯罪攻击的攻击。 有关详细信息,请参阅 breachattack.com 。工作原理这里 ...
Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zipRuby_on_Rails_rails.zip Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zip Ruby_on_Rails_rails.zipRuby_on_...
安装将这些行添加到应用程序的Gemfile中: gem ' foundation-rails 'gem ' autoprefixer-rails ' 然后执行: bundle 或将其自己安装为: gem install foundation-rails配置基础您可以运行以下命令来添加Foundation:...
adminlte-rails, AdminLTE Rails gem 将AdminLTE主题与 Rails 资产管道集成 AdminLTE Rails gem AdminLTE 是后端的高级 Bootstrap 主题。英镑 AdminLTE Rails gem 与 Rails 资产管道集成了英镑AdminLTE主题。安装将...
tinymce-rails, 集成TinyMCE与 Rails 资产管道 用于TinyMCE的 Rails 集成tinymce-rails gem 将 TinyMCE 编辑器与 Rails 资产管道集成在一起。这里 gem 与 Rails 3.1.1和更高的( 包括 Rails 4 ) 兼容。这是 Tiny