2012-04-11 38 views
4

時,我一直工作在解析字符串和我有一個已經造成的問題對我來說是測試用例。使用strptime解析日期/時間字符串時,夏時制不計算在內。據我所知,這是一個錯誤。我找不到有關此錯誤的任何文檔。這是Rails控制檯中的一個測試用例。這是ruby 1.9.3-p215和Rails 3.2.2。Rails的夏令時沒有考慮使用DateTime.strptime

1.9.3-p125 :049 > dt = DateTime.strptime("2012-04-15 10:00 Central Time (US & Canada)", "%Y-%m-%d %H:%M %Z") 
=> Sun, 15 Apr 2012 10:00:00 -0600 
1.9.3-p125 :050 > dt = DateTime.strptime("2012-04-15 10:00 Central Time (US & Canada)", "%Y-%m-%d %H:%M %Z").utc 
=> Sun, 15 Apr 2012 16:00:00 +0000 
1.9.3-p125 :051 > dt = DateTime.strptime("2012-04-15 10:00 Central Time (US & Canada)", "%Y-%m-%d %H:%M %Z").utc.in_time_zone("Central Time (US & Canada)") 
=> Sun, 15 Apr 2012 11:00:00 CDT -05:00 

正如你所看到的,我必須轉換爲UTC,然後返回到時區獲得DST進行正確解釋,但隨後的時間移動一個每小時很好,所以這不是我分析出的字符串。是否有人對此錯誤採取瞭解決方法,或者將日期+時間+時區可靠地解析爲日期時間對象恰當表示的日期時間對象?謝謝。

編輯: 好吧,我找到了一個解決辦法,但我不知道它是多麼強勁。

下面是一個例子:

ActiveSupport::TimeZone["Central Time (US & Canada)"].parse "2012-04-15 10:00" 

這解析日期/時間字符串到正確的時區。我不確定解析方法對於處理這個有多強大,所以我想看看是否有更好的解決方法,但這是迄今爲止我的方法。

回答

0

好吧,這裏是我發現迄今處理這個的最佳方式。我在一個lib文件中創建了一個實用程序方法。

# Returns a DateTime object in the specified timezone 
def self.parse_to_date(date_string, num_hours, timezone) 
    if timezone.is_a? String 
    timezone = ActiveSupport::TimeZone[timezone] 
    end 

    result = nil 
    #Chronic.time_class = timezone # Trying out chronic time zone support - so far it doesn't work 
    the_date = Chronic.parse date_string 
    if the_date 
    # Format the date into something that TimeZone can definitely parse 
    date_string = the_date.strftime("%Y-%m-%d") 
    result = timezone.parse(date_string) + num_hours.to_f.hours 
    end 

    result 
end 

注意,我添加到時間手動因爲Chronic.parse是不夠健壯,因爲我在解析次喜歡的時間 - 它失敗時沒有尾隨零添加到時間,例如,在8 :0而不是8:00。
我希望這對某人有用。將日期/時間/ timzone字符串解析爲有效日期似乎是一件非常常見的事情,但我無法找到將所有三者合併在一起的任何解析代碼。

+0

您可以像這樣設置慢性時區 Chronic.time_class = ActiveSupport :: TimeZone ['Mexico City'] – 2015-03-21 01:05:54

5

這是一個令人沮喪的問題。您正在尋找的Rails方法是Time.zone.parse。首先使用DateTime.strptime解析字符串,然後運行它通過Time.zone.parse設置的區域。看看下面的控制檯輸出:

> Time.zone 
=> (GMT-06:00) Central Time (US & Canada) 
> input_string = "10/12/12 00:00" 
> input_format = "%m/%d/%y %H:%M" 
> date_with_wrong_zone = DateTime.strptime(input_string, input_format) 
=> Fri, 12 Oct 2012 00:00:00 +0000 
> correct_date = Time.zone.parse(date_with_wrong_zone.strftime('%Y-%m-%d %H:%M:%S')) 
=> Fri, 12 Oct 2012 00:00:00 CDT -05:00 

注意,即使Time.zone的偏移量爲-6(CST),最終結果的偏差爲-5(CDT)。