程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Rails+MySQL開發中的時間問題

Rails+MySQL開發中的時間問題

編輯:關於JAVA

MySQL中的時區

顯示時區信息

mysql> show variables like '%time_zone%'; 
+------------------+--------+ 
| Variable_name    | Value  | 
+------------------+--------+ 
| system_time_zone | CST    | 
| time_zone        | SYSTEM | 
+------------------+--------+ 
2 rows in set (0.00 sec)

設置時區信息

+8:00是中國所在的時區,東八區。

mysql> set time_zone = '+8:00';

Query OK, 0 rows affected (0.00 sec)

Rails中的時區

rails默認就是寫入utc時間,然後讀取也是utc時間。

設置config.time_zone只能保證寫入數據庫的時間是local,就是保證創建對象的時候created_at和updated_at使用設置的本地時間。

但是讀出來的時候還是有可能是utc時間,有可能需要在界面上轉換的。

rails推薦使用utc時間,這樣就統一了,只是在界面顯示的時候格式化為本地時間。

rake time:zones:all #查看所有時區

rake time:zones:local #查看本地時區

默認情況

我們使用

rails g scaffold post title:string content:string

生成一個model之後,打開【db/migrate/201200_create_posts.rb】文件看到下面的內容。

class CreatePosts < ActiveRecord::Migration 
  def change 
    create_table :posts do |t| 
      t.string :title 
      t.string :content 
     
      t.timestamps 
    end
  end
end

t.timestamps會幫我們在數據庫中生成created_at和updated_at兩個字段,這兩個字段rails會自動賦值不用我們手動指定。

在界面上添加post之後,打開log/production.log文件,會看到下面的內容。

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中添加

config.log_level = debug

debug的級別會在日志中記錄每個sql,方便調試。在發布到生產環境之後,修改這個級別信息。

請注意created_at的值,明明是中國時間中午插入的記錄,但是insert語句中的時間卻是utc時間,落後八個小時,因為中國是東八區+8:00。

插入數據庫的值自然也就是這個utc時間。

設置時區之後

解決這個問題可以在config/application.rb文件中添加下面的配置。

config.active_record.default_timezone = :local

config.time_zone = 'Beijing'

再次插入數據,打開log文件,就會發現時間變成了北京時間,插入數據庫的也是北京時間。進入mysql -u root -p之後,查詢的結果也是北京時間。

在view文件中使用

<%= created_at %>

顯示的結果是

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

是沒有問題的,但是多了時區+0800信息。

要是使用

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

顯示的結果就是

2012-11-01 05:39:26

沒有了+0800,但是時間又變成了utc時間了。

使用

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

就變成

2012-11-01 13:39:26

這下沒有時區+0800信息,時間也是本地時間了。就是先轉換為本地時間,然後在進行格式化。

created_at.utc  #轉換為utc時間

created_at.localtime  #轉換為local時間

還有就是在rails console中有一點特別。

1.9.3-p286 :013 > p=Post.last
  Post Load (0.3ms)  SELECT `posts`.* FROM `posts` ORDER BY `posts`.`id` DESC LIMIT 1 
 => #<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>  
1.9.3-p286 :014 > p.created_at 
 => 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時間,這樣就統一了,只是在界面顯示的時候格式化為本地時間。

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

出處http://virusswb.blog.51cto.com/115214/1046723

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved