_DateTime.strptime
_で解析する文字列があります。文字列内の日付のタイムゾーンはCETですが、Rubyは、もちろん2時間のオフセットを持つUTCDateTimeオブジェクトを作成します。
現在、私はDateTime.strptime().change(:offset => "+0020")
の問題を回避していますが、これが意図したとおりの方法ではないと確信しています。
誰かがこれを行う正しい方法について私に教えてもらえますか?
私はそれを次のように使用します:
Ruby-1.9.2-head :001 > require 'date'
=> true
Ruby-1.9.2-head :002 > fmt = "%m-%d-%Y %H:%M:%S %Z"
=> "%m-%d-%Y %H:%M:%S %Z"
Ruby-1.9.2-head :003 > DateTime.strptime "10-26-2011 10:16:29 CET", fmt
=> #<DateTime: 2011-10-26T10:16:29+01:00 (212186380589/86400,1/24,2299161)>
Ruby-1.9.2-head :004 > DateTime.strptime "10-26-2011 10:16:29 UTC", fmt
=> #<DateTime: 2011-10-26T10:16:29+00:00 (212186384189/86400,0/1,2299161)>
Ruby-1.9.2-head :005 > DateTime.strptime "10-26-2011 10:16:29 PST", fmt
=> #<DateTime: 2011-10-26T10:16:29-08:00 (212186412989/86400,-1/3,2299161)>
それはどういう意味ですか?
これはRails 5:
Time.zone.strptime("2017-05-20 18:20:10", "%Y-%m-%d %H:%M:%S")
指定されたタイムゾーンの時間を返します。
少なくともRails 4.2(おそらく以前、テストされていません)の時点では、Time#strptime
の代わりにDateTime.strptime
を使用している限り、現在のタイムゾーンが自動的に適用されます。
> DateTime.strptime('12/28/2016 5:00 PM', '%m/%d/%Y %H:%M %p')
=> Wed, 28 Dec 2016 17:00:00 +0000
> Time.strptime('12/28/2016 5:00 PM', '%m/%d/%Y %H:%M %p')
=> 2016-12-28 17:00:00 -0800
私はこの文字列を「strptiming」していました:
_19/05/2014 8:13:26 a.m.
_
私の場合、ローカルタイムスタンプはAuckland NZで、文字列にタイムゾーンスタンプがありません。
_Time.strptime
_はサーバーのタイムゾーンをベースとして使用していることがわかります。
私の状況と一般的なグッドプラクティスでは、サーバーはUTCタイムゾーンで実行されるため、文字列を解析するたびに、+ 0000(UTC)までの時間オブジェクトが作成されます。
_2014-05-19 08:13:26 +0000
_
次に、in_time_zone(Time.zone)
に変換すると次のようになります。
_Mon, 19 May 2014 20:13:26 NZST +12:00
_
ご覧のとおり、実際の時間より12時間(UTCオフセット)遅れています。
上記のように_+' Auckland', '...%Z'
_トリックを変更せずに使用しようとしました。次に、上記の_+ '+1200', '...%Z'
_トリックを使用しました。これは正しく機能しました。
しかし、私は夏の時間を心配していました、そしてそれから解析は1時間で終わるでしょう、それでこれは私が仕上げたものです:
_Time.strptime(call_data[:datetime].gsub(/\./, "").gsub(/am/, "AM").gsub(/pm/, "PM") + (Time.zone.now.time_zone.utc_offset/3600).to_s.ljust(4,'0').rjust(6,' +'), '%d/%m/%Y %I:%M:%S %p %Z').in_time_zone(Time.zone)
_
結果:
_Mon, 19 May 2014 08:13:26 NZST +12:00
_
それは特にエレガントではありませんが、機能します。
Pre Rails 5の場合、以下が機能します。
t0 = Time.strptime("2018-05-01", "%Y-%m-%d") # Or whatever
t1 = Time.zone.now.change(year: t0.year, month: t0.month, day: t0.day, hour: t0.hour, min: t0.min, sec: t0.sec, usec: t0.usec)
to_time_in_current_zone
を使用して日付をタイムゾーンに変換できます。例えば:
Date.strptime('04/07/1988', '%m/%d/%Y').to_time_in_current_zone
私は、フォームから日付文字列を解析し、サーバーの時間とは関係なく保存しようとして、この同じ問題と戦ってきました。私が従ったプロセスはそのようなものです。 RoRとRubyタイムゾーンがUTCに設定されていることを確認します。サーバーがUTC時間にある場合も、簡単になります。
US/Eastern
のようなActiveSupport:TimeZone形式を使用してユーザーロケールを保存しています。タイムゾーンまたはオフセットをネイティブに含まない日付文字列を説明できる日付解釈関数があります。
# date_str looks something like this `12/31/2014 6:22 PM`
# tz is a string containing an ActiveSupport::TimeZone name like `US/Eastern`
def interpret_date(date_str, tz)
Time.use_zone tz do
parsed_dt = DateTime.strptime(date_str, '%m/%d/%Y %H:%M %p')
offset = parsed_dt.in_time_zone(tz).utc_offset
parsed_dt.advance(seconds: -(offset)).in_time_zone(tz)
end
end
もちろん、これは完璧な解決策のようには感じられませんが、機能します。正しいタイムゾーンを確保するための手順は次のとおりです。