Rails+MySQL開發中的時間問題

來源:互聯網
上載者:User

 

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時間,這樣就統一了,只是在介面顯示的時候格式化為本地時間。

對於任何應用來說,遇到時區問題,都應該考慮語言本身和儲存本身,甚至是作業系統本身的時區設定和一些預設值,這樣才能最終較好的解決時區問題。

 

參考文獻

1.Convert local time to UTC in Rails

2.Rails 3 default datetime format without UTC

3.rails 有關時區的設定的問題

4.Date Time Format in RUBY

5.rails time format

6.完美解決rails中國時區時間設定

7.Time Zones in Rails 2.1

8.MySQL時區設定

9.Rails內建的時間格式化

 

本文出自 “突破中的IT結構師” 部落格,請務必保留此出處http://virusswb.blog.51cto.com/115214/1046723

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.