`
280862132
  • 浏览: 85834 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

时区与程序-Rails 分享

阅读更多
转自 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 基于java的开发源码-Rails3消息队列系统 Sidekiq.zip ...

    jquery-datatables-rails, 用于 Rails的jquery数据表 gem.zip

    jquery-datatables-rails, 用于 Rails的jquery数据表 gem jquery-datatables-rails 这个 gem 为 jQuery DataTables插件提供了方便,以便与 Rails 资产pipleine结合使用。 它提供所有基本的datatable文件,以及一些...

    关于rails 3.1 cucumber-rails 1.2.0

    Cucumber-Rails集成了Cucumber与Rails,使得开发者能够在Rails环境中方便地使用Cucumber进行功能测试。 在 Rails 应用中使用 Cucumber-Rails,开发者可以创建一个名为`features`的目录,里面包含这些Gherkin特性...

    jquery-fileupload-rails, 用于 Rails的jQuery文件上传集成.zip

    jquery-fileupload-rails, 用于 Rails的jQuery文件上传集成 Rails 文件上传jQuery-File-Plugin 是一个文件上传插件,由的Tschan 。 jQuery文件上传功能多文件选择。drag&拖放支持。进度栏和jQuery预览图像。 支持...

    turbo-sprockets-rails3, 加速你的Rails 3资产.zip

    turbo-sprockets-rails3, 加速你的Rails 3资产 用于 Rails 3.2.x的涡轮链轮 通过只根据源文件的哈希来重新编译已经更改的资产,从而加快 Rails 3 rake assets:precompile的速度只编译一次以生成指纹和非打印的资产...

    Angle-3.4-rails

    "Angle-3.4-rails"是一个专门针对Rails框架的项目,其包含了"backend-rails"和"backend-rails-seed"两个关键部分,旨在为开发者提供一个强大的后端开发环境和数据初始化工具。 一、Rails框架介绍 Rails是由David ...

    projectile-rails, 基于弹丸的Rails 模式.zip

    projectile-rails, 基于弹丸的Rails 模式 弹 Rails 概要弹 Rails 是在 GNU Emacs中使用 Ruby on Rails 应用程序和引擎的次要模式。 在内部,它是基于弹 。这意味着你可以在 greping ( 或者 acking ) 文件。运行测试...

    jquery-ui+jquery-ui-rails

    在这个案例中,我们看到`jquery-ui-rails-4.2.1.gem`,这是该gem的一个特定版本。这个gem负责将jQuery UI的库文件打包并整合到Rails的asset pipeline中,使得在Rails项目中使用jQuery UI变得简单。 要使用`jquery-...

    influxdb-rails-源码.rar

    《InfluxDB与Rails集成深度解析——以influxdb-rails源码为例》 InfluxDB,作为一款专为时间序列数据设计的高性能数据库,被广泛应用于监控、物联网、大数据分析等领域。Rails,作为Ruby on Rails框架的核心部分,...

    webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成.zip

    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 引擎.zip

    grape-swagger-rails, Swagger UI作为葡萄 Swagger gem的Rails 引擎 GrapeSwaggerRails Swagger UI作为葡萄 Swagger gem的Rails 引擎。安装将此行添加到你的应用程序的Gemfile中:gem 'grape-swagger-rails'

    Ruby-Rails的Clojurescript集成类似于webpackrails

    Clojurescript的使用不仅限于Rails,它还可以与其他框架和库结合,如React、Ember等,提供了一种不同于JavaScript的开发体验。Clojurescript的函数式编程特性、宏系统和Lisp风格的语法,对于一些开发者来说,可能...

    minitest-rails, Rails的Minitest集成.zip

    minitest-rails, Rails的Minitest集成 minitestRails 5的Minitest集成 安装gem install minitest-rails这将安装以下宝石:minitest配置创建一个新的Rail

    to_xls-rails:将Rails ActiveRecord或Mongid数据导出到Excel文件

    这个简单的插件使您能够调用to_xls到Rails的数组集合。 数组元素支持对象:ActiveRecord,Mongid,哈希。 在您的Gemfile中: gem 'to_xls-rails' # Last officially released gem # gem "to_xls-rails", :git => ...

    jquery-ui-rails:Rails资产管道的jQuery UI

    警告:此gem与3.0.0之前的jquery-rails gem不兼容! 如果您使用早期的jquery-rails版本,将会发生奇怪的事情。 运行bundle list ,以确保你要么不使用jquery-rails ,或者至少是3.0.0版本的jquery-rails 。 用法 在...

    breach-mitigation-rails, 使 Rails 应用程序更能抵御入侵和犯罪攻击.zip

    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.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_...

    foundation-rails:Rails基础

    安装将这些行添加到应用程序的Gemfile中: gem ' foundation-rails 'gem ' autoprefixer-rails ' 然后执行: bundle 或将其自己安装为: gem install foundation-rails配置基础您可以运行以下命令来添加Foundation:...

    adminlte-rails, AdminLTE Rails gem 将AdminLTE主题与 Rails 资产管道集成.zip

    adminlte-rails, AdminLTE Rails gem 将AdminLTE主题与 Rails 资产管道集成 AdminLTE Rails gem AdminLTE 是后端的高级 Bootstrap 主题。英镑 AdminLTE Rails gem 与 Rails 资产管道集成了英镑AdminLTE主题。安装将...

    tinymce-rails, 集成TinyMCE与 Rails 资产管道.zip

    tinymce-rails, 集成TinyMCE与 Rails 资产管道 用于TinyMCE的 Rails 集成tinymce-rails gem 将 TinyMCE 编辑器与 Rails 资产管道集成在一起。这里 gem 与 Rails 3.1.1和更高的( 包括 Rails 4 ) 兼容。这是 Tiny

Global site tag (gtag.js) - Google Analytics