9

Dateオブジェクトを特定のタイムゾーンでのその日の始まりを表すTimeWithZoneオブジェクトに変換する必要があります。

次のアプローチは機能しますが、日付を文字列に変換する必要があるため、複雑すぎるようです。

?> date = Date.parse("2010-02-17")
=> Wed, 17 Feb 2010
>> ActiveSupport::TimeZone['Eastern Time (US & Canada)'].parse(date.to_s)
=> Wed, 17 Feb 2010 00:00:00 EST -05:00
>> ActiveSupport::TimeZone['UTC'].parse(date.to_s)
=> Wed, 17 Feb 2010 00:00:00 UTC 00:00

私が行方不明になっているより良い方法はありますか?

編集:人々は次のバリエーションを提案しています:

?> date.to_datetime.in_time_zone('Eastern Time (US & Canada)').beginning_of_day
=> Tue, 16 Feb 2010 00:00:00 EST -05:00

ご覧のとおり、これは2月17日ESTの開始ではなく、2月16日ESTの開始時に私を残すため、同等の変換ではありません。

4

5 に答える 5

10

私はパーティーに遅れましたが、これはまだ素晴らしい質問です. OP以降にActiveSupportin_time_zoneが導入されましたが、文字列を解析したり(遅い)、Time.zoneを設定したり(危険)せずに、必要なことを正確に実行します。

>> date = Date.parse("2010-02-17")
=> Wed, 17 Feb 2010
>> date.in_time_zone('Eastern Time (US & Canada)')
=> Wed, 17 Feb 2010 00:00:00 EST -05:00

もちろん、1 日の始まりを utc で表現したい場合は、次のようにすることができます。

>> date.in_time_zone('Eastern Time (US & Canada)').utc
=> 2010-02-17 05:00:00 UTC
于 2013-11-02T10:07:35.743 に答える
4

Time.zoneRails で設定した場合は、呼び出すことができますDate#at_beginning_of_day( http://api.rubyonrails.org/classes/Date.html#method-i-at_beginning_of_dayを参照)。これを と対比してDate#to_datetimeください:

Time.zone
 => #<ActiveSupport::TimeZone:0x10cf10858 @tzinfo=#<TZInfo::TimezoneProxy: Etc/UTC>, @utc_offset=nil, @current_period=nil, @name="UTC"> 

date = Date.today
 => Thu, 31 May 2012 

date.to_datetime
 => Thu, 31 May 2012 00:00:00 +0000 

date.at_beginning_of_day
 => Thu, 31 May 2012 00:00:00 UTC +00:00 

Time.zone = 'America/Chicago'
 => "America/Chicago" 

date.to_datetime
 => Thu, 31 May 2012 00:00:00 +0000 

date.at_beginning_of_day
 => Thu, 31 May 2012 00:00:00 CDT -05:00
于 2012-05-31T21:04:58.757 に答える
2

to_datetime使用する、またはto_timeゾーンを認識しないために日付を時刻に変換するソリューションには強くお勧めしますin_time_zone。一部の回答が示唆しているように、結果に取り組むことで間違いをさかのぼって修正することはできません。また、UTCオフセットを使用して独自の夏時間計算を作成しようとしないでください。あなたはそれを間違えるに違いない、そしてあなたは不必要に仕事をしている。

このロジックが組み込まれているTimeZone自体を使用してください。

ゾーンと日付を指定すると、次のように1日の始まりのTimeWithZoneを取得できます。

time = zone.local(date.year, date.month, date.day)

開始以外の特定の時刻が必要な場合は、時間、分、秒を4番目、5番目、6番目の引数としてに渡すことができます#local

zoneが実際にシステムのローカルタイムゾーン( )である場合Time.zone、ActiveSupportでは上記を次のように短縮できます。

time = date.to_time_in_current_zone

上記のすべてが夏時間を正しく処理します。UTCオフセットを2回見て、1つはDSTの外側にあり、もう1つはDSTの内側にあることを確認しましょう。

irb(main):009:0> zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
=> (GMT-05:00) Eastern Time (US & Canada)
irb(main):010:0> t1 = zone.local(2013, 1, 1)
=> Tue, 01 Jan 2013 00:00:00 EST -05:00
irb(main):011:0> t2 = zone.local(2013, 5, 1)
=> Wed, 01 May 2013 00:00:00 EDT -04:00
irb(main):012:0> t1.utc_offset
=> -18000
irb(main):013:0> t2.utc_offset
=> -14400
于 2013-02-12T18:03:15.557 に答える
0

utc_offset を減算します。

d = Date.today
Time.zone.class.all.map(&:name).map { |tz| dt = d.to_datetime.in_time_zone(tz); dt -= dt.utc_offset }

ActiveSupport::TimeZone[tz] を使用すると、夏時間が考慮されません。

Time.zone.class.all.map(&:name).map { |tz| o = d.to_datetime.in_time_zone(tz).utc_offset - ActiveSupport::TimeZone[tz].utc_offset }
于 2011-05-19T06:14:35.333 に答える
0

このようなものはあなたのために働くでしょうか?

'2010-04-01'.to_time.in_time_zone('Eastern Time (US & Canada)').beginning_of_day
于 2010-03-25T21:29:23.737 に答える