2012-05-04 106 views
4

我的應用在「莫斯科」(+04:00)時區工作。但有時我需要僅在當地時間創建時間對象(例如「01 May 2012 13:45」)和ActiveSupport :: TimeZone對象的名稱(例如「柏林」:夏季+02:00和+01:否則爲00)。Rails:如何在特定時區創建時間對象

例如,如果我得到「01 May 2012 13:45」和「Berlin」作爲輸入,我想要產生「2012-05-01 13:45:00 +0200」或「2012-05-01 11: 45:00 +0000「。我創建以下功能:

def from_local_datetime(local_datetime, time_zone) 
    offset = Time.now.in_time_zone(time_zone).formatted_offset 
    datetime = case local_datetime 
    when String 
    DateTime.parse(local_datetime) 
    else 
    DateTime.new(local_datetime) 
    end.change(:offset => offset) 

    return datetime 
end 

而在第一次看,它的工作原理與我的預期。但這是這種任務的最佳做法嗎?可能在某些情況下它有錯誤。我不確定。

我對任何評論都很感激。

UPD:我認爲當DST改變時間時可能會出現錯誤。例如2011年3月26日是格林威治標準時間+ 1在柏林時區和Time.now.in_time_zone("Berlin").formatted_offset返回「格林威治標準時間+1」,但它將在2011年3月27日格林威治標準時間+2。因此,如果我在3月27日之前致電from_local_datetime("28 march 2011", "Berlin")它返回28 march 2011 00:00:00 +0100,但如果我打電話它改變時間後,我的函數返回28 march 2011 00:00:00 +0200 :(

+0

我不理解的錯誤。柏林標準時間(冬季)是UTC /(格林威治標準時間)+1。也就是說,當它在格林威治/巴黎的中午時,已經是柏林的13:00了。今年夏天,柏林人在標準時間之前設置時鐘,所以在UTC或格林尼治標準時間的中午,柏林的時間是14:00。 –

+0

從上面的代碼可以看到,我通過以下代碼獲得柏林時區的當前偏移量:'Time.now.in_time_zone(time_zone).formatted_offset'(+1,如果Time.now是2011年3月27日)。但是我需要在柏林抵消'2011年3月28日'(抵消將是+2)。 – petRUShka

回答

0

你的轉換方法是正確的做法。

與網站,你應該確保時間存儲在數據庫中的UTC,如果你能得到UTC價值出數據庫,而不是本地時間(或者,也許你可以設置你的Web服務器的時區爲UTC),它不需要將時間從UTC轉換到本地時間,當你打算將它轉換爲無論如何用戶的時區。

而且,當然,您將不得不存儲用戶的時區首選項。

+0

請參閱原始靜態更新 – petRUShka

0
TZInfo::Timezone.get('Europe/London') 

找到時區

http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html 
相關問題