4

私は文字列の解析に取り組んでおり、問題を引き起こしているテスト ケースがあります。strptime で日付/時刻文字列を解析する場合、夏時間は考慮されません。これは私が知る限りバグです。このバグに関するドキュメントが見つかりません。Rails コンソールでのテスト ケースを次に示します。これは ruby​​ 1.9.3-p215 と Rails 3.2.2 です。

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  

ご覧のとおり、DST を適切に解釈するには、utc に変換してからタイムゾーンに戻す必要がありますが、時刻も 1 時間ずれているため、文字列から解析したものではありません。誰かがこのバグの回避策、または日付 + 時間 + タイムゾーンを確実に解析して、夏時間が適切に表される DateTime オブジェクトにするより堅牢な方法を持っていますか? ありがとうございました。

編集:わかりました、回避策を見つけましたが、それがどれほど堅牢かはわかりません。

次に例を示します。

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

これにより、日付/時刻文字列が正しいタイムゾーンに解析されます。これを処理するための parse メソッドがどれほど堅牢かはわかりませんので、より良い回避策があるかどうかを確認したいと思いますが、これは今のところ私の方法です。

4

2 に答える 2

6

これはイライラする問題です。あなたが探している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) であることに注意してください。

于 2012-10-12T18:11:36.613 に答える
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:00 ではなく 8:0 のように、時間に末尾のゼロが追加されなかった場合に失敗しました。 .
これが誰かに役立つことを願っています。日付/時刻/タイムゾーン文字列を有効な日付に解析することは非常に一般的なことのようですが、3 つすべてを組み合わせた解析コードを見つけることができませんでした。

于 2012-04-16T16:24:37.923 に答える