Rails之關於時間(時區)

2021-08-03 03:50:59 字數 4370 閱讀 3269

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,所以timeactivesupport::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...