it』s about time (zones)
這是時間系列的第一篇文章。第二篇的主題是 a case study in multiple time zones。
和datetime
。ruby1.9.3之後兩者之間的區別越來越小。鑑於time
包含閏秒和夏令時的概念。本文中,我們將使用time
來舉例。
tzinfo是乙個時區庫,提供不同時區的夏令時轉換。它被封裝成了gem並且包含582個不同時區的資料。
rails中的activesupport::timezone封裝了tzinfo,並提供其中146個時區的資料以及更好的時區格式(例如:用eastern time (us & canada)
替換america/new_york
)。另外配合 activesupport::timewithzone,rails提供和ruby中time
類一樣的api,所以time
和activesupport::timewithzone
是可以互換的,你永遠都不需要直接建立乙個timewithzone
例項(new)
執行以下命令檢視rails中所有可用的時區:
$ rake time:
zones:all
* utc -11
:00 *
american
samoa
international
date
line
west
midway
island
samoa
* utc -10
:00 *
hawaii
* utc -09:
00 *
alaska
...
在console中檢視當前時區:
> time.zone
=> #@current_period=#>>,
@name="utc",
@tzinfo=#,
@utc_offset=nil>
或臨時設定時區:
# in console
> time.zone = "perth"
config.time_zone = "perth"
假設每個使用者都擁有自己的時區。這個可以通過向user表新增time_zone屬性實現:
create_table :users
do |t|
t.string :time_zone, default:
"utc"
...end
將時區儲存為字串形式是因為rails中大多數時區相關方法都接受字串。因此,應該避免將時區儲存為:enums
格式。
使用者可以設定自己想要的時區。******form支援:time_zone
,並且提供了乙個help方法讓使用者可以在下拉框中選擇時區。
<%= f.input :time_zone %>
around_action :set_time_zone, if:
:current_user
private
defset_time_zone(&block)
time.use_zone(current_user.time_zone, &block)
end我們將使用者的時區資訊傳遞給time.use_zone
(activesupport提供的方法)。該方法需要傳遞乙個塊,在塊的範圍內設定時區。所以它只影響一次請求,請求結束之後使用的還是原始時區(應用預設時區)。
在rails 3.2.13及更低版本中,需要使用around_filter
替代around_action
。
最後,在展示時區時,可以使用in_time_zone
方法:
<%= time.in_time_zone(current_user.time_zone) %>
操作api時最好使用iso8601標準,該標準用字串表示日期時間。iso8601的優點是清晰,可讀,廣泛支援並且是按規則排序的。示例:
> timestamp = time.now.utc.iso8601
=> "2015-07-04t21:53:23z"
結尾處的z代表utc時間,可以使用以下方法將字串轉為時間物件:
> time.iso8601(timestamp)
=> 2015-07-0421:
53:23utc
在乙個rails應用中,存在三個不同的時區:
假設我們將時區設為fiji,來看下結果:
# this is the time on my machine, also commonly described as "system time"
> time.now
=> 2015-07-0417:
53:23 -0400
# let's set the time zone to be fiji
> time.zone = "fiji"
=> "fiji"
# but we still get my system time
> time.now
=> 2015-07-0417:
53:37 -0400
# however, if we use `zone` first, we finally get the current time in fiji
> time.zone.now
=> sun, 05
jul2015 09:53:
42fjt +12:00
# we can also use `current` to get the same
> time.current
=> sun, 05
jul2015 09:54:
17fjt +12:00
> time.now.in_time_zone
=> sun, 05
jul2015 09:56:
57fjt +12:00
# let's do the same with date (we are still in fiji time, remember?)
# this again is the date on my machine, system date
> date.today
=> sat, 04
jul2015
> time.zone.today
=> sun, 05
jul2015
> time.zone.tomorrow
=> mon, 06
jul2015
# going through rails' helpers, we get the correct tomorrow as well
> 1.day.from_now
=> mon, 06
jul201510:
00:56fjt +12
:00
rails使用utc時區將時間戳存入資料庫。在資料庫查詢中應該始終使用time.current
,rails會幫我們轉換成正確的時間進行對比。
post.where("published_at > ?", time.current)
# select "posts".* from "posts" where (published_at > '2015-07-04 17:45:01.452465')
不要使用
* time.now
* date.today
* date.today.to_time
* time.parse("2015-07-04 17:05:37")
* time.strptime(string, "%y-%m-%dt%h:%m:%s%z")
推薦使用
* time.current
* 2.hours.ago
* time.zone.today
* date.current
* 1.day.from_now
* time.zone.parse("2015-07-04 17:05:37")
* time.strptime(string, "%y-%m-%dt%h:%m:%s%z").in_time_zone
關於Linux的時間與時區
首先要說明的是我的系統是fedora,其他系統可能不完全相同。1,時間儲存在硬體實時鐘 rtc 中,rtc由主機板電池供電,即使關斷電源也不會造成時間丟失。2,系統啟動時從rtc獲取時間,這個步驟在rc.sysinit中做 a,首先從 etc sysconfig clock中獲取rtc相關引數utc...
mysql 時區 時間轉換 MySQL時間時區轉換
將timestamp轉換為指定時區的時間,如 2018 09 21 11 48 42 select convert tz create time,session.time zone,8 00 from auth user 將timestamp轉換為指定時區的時間,並精確到天數,如 2018 09 2...
rails 表示時間
time time.now time time.now time 得到當前本地時間,thu jun 07 01 04 38 0800 2007 time 得到當前本地時間,thu jun 07 01 04 38 0800 2007 time.gmtime 得到格林威治時間,wed jun 06 17...