2

ローカルマシンでは、RVMを使用しています

>> ruby -v
=> ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux]

# in the terminal
>> date
=> Wed Feb 27 20:00:17 PHT 2013

ステージングサーバーでは、rbenvを使用しています

>> ruby -v
=> ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]

# in the terminal
>> date
=> Wed Feb 27 12:00:22 UTC 2013

私のローカルマシンでは、ajax呼び出しから来た日付文字列を解析しています

>> Time.zone
=> (GMT+00:00) UTC
>> Time.zone.parse('Wed Feb 27 2013 19:46:21 GMT+0800 (PHT)')
=> Wed, 27 Feb 2013 19:46:21 UTC +00:00

ステージングサーバーでは、異なる結果が得られます

>> Time.zone
=> (GMT+00:00) UTC
>> Time.zone.parse('Wed Feb 27 2013 19:46:21 GMT+0800 (PHT)')
=> Wed, 27 Feb 2013 11:46:21 UTC +00:00

ステージングサーバーで解析結果をタイムゾーンに認識させる方法はありますか?

4

1 に答える 1

4

JavascriptとRubyは同じ時間形式を使用しないため、不一致があります。Javascriptが使用するもの(RFC 1123)は廃止されており、RFC2822やISO8601などを想定したRuby日時解析メソッドの実装によって誤って読み取られます。この不一致は、Javascriptを次のように出力することで修正されます。 ISO形式。

なぜ

ActiveSupport::TimeZone#parseを使用している場合は、文字列を内部的Time::parseに直接使用して時刻を取得し、目的のタイムゾーンに配置します。

あなたの場合、文字列はデフォルトのjavascriptメソッドによって出力されましたDate.prototype.toString。これは通常、RFC 1123形式を提供します(ただし、実装によって異なります)。これは、 RFC2822およびISO8601ではほとんど廃止されています。

さまざまな時間標準(RFC、RFC、RFC!)に関するメモ

RFC1123では、「GMT + 0800」などの「GMT」文字列でタイムゾーンを表すことができますが、RFC2822では、「GMT」/「UT」とは言わずに、統一UTC表現「+0800」を優先してその文字列を廃止していますISO8601はさらにコンパクト20130227T0914-0500であるため(たとえば)、「GMT」と言うこともできません。

ルビーに戻ってきます

したがって、Time::parseを使用するはTime::zone_offset、そのタイムゾーン情報(特に「GMT」と混同)を認識できず、システムのタイムゾーンにフォールバックします。

標準の時間形式を使用する

したがって、実際、Saurabhが指摘しているように、それはクライアントが時間を文字列にシリアル化する方法の問題です。私が提案するのは、解析された文字列を、 RFC2822 (フォーマットに似ている)やISO8601などの標準フォーマットを使用するように変更することです。その場合、あなたの時間は正しく解析されるべきです。

irb(main):049:0> Time.zone.parse('Wed Feb 27 2013 19:46:21 GMT+0800 (PHT)')
=> Thu, 28 Feb 2013 00:46:21 UTC +00:00
irb(main):050:0> Time.zone.parse('Wed Feb 27 2013 19:46:21 +0800 (PHT)')
=> Wed, 27 Feb 2013 11:46:21 UTC +00:00

私が行った簡単なテストでは、JavascriptはRFC 2822文字列(「GMT」なし)を簡単に出力できないようです。ただし、まだ外に出ないでください。gsub「GMT」または「UTC」が永久に存在するという保証はありません。幸い、ISOは簡単に実行できるようです。(フォーマットがあなたの好みに合うなら、それは; o))

> new Date();
Wed, 27 Feb 2013 13:22:20 GMT # bad
> (new Date()).toString();
'Wed Feb 27 2013 08:22:25 GMT-0500 (EST)' # bad
> (new Date()).toUTCString();
'Wed, 27 Feb 2013 13:22:31 GMT' # still bad :(
> (new Date()).toISOString();
'2013-02-27T13:22:57.310Z' # good

これに触れられない!(Javascriptクライアント)

または、クライアントの変更に問題がない場合、または迅速で汚い修正を探している場合は、Date::_parse代わりに使用できます。これは、オフセットを正しく把握しているようです。

irb(main):052:0> d = Date._parse('Wed Feb 27 2013 19:46:21 +0800 (PHT)')
=> {:wday=>3, :zone=>"+0800", :hour=>19, :min=>46, :sec=>21, :year=>2013, :mon=>2, :mday=>27, :offset=>28800}
irb(main):053:0> Time.new(d[:year], d[:mon], d[:mday], d[:hour], d[:min], d[:sec], d[:offset])
=> 2013-02-27 19:46:21 +0800

ただし、このメソッドは内部の日付解析関数を使用しているため、長期的に信頼できるかどうかはわかりません。さらに、標準の時間文字列を使用することをお勧めします。

だから子供たちを覚えておいてください、標準はあなたの友達です!それらを使用してください!

于 2013-02-27T12:58:34.093 に答える