DebianでRails 3.2およびRuby 1.9.3を使用しています。文字列の形式で日付、時刻、およびタイムゾーンを収集するアプリがありますHTMLフォーム経由で。次のようなものです。
start_date: "04-15-2010",
start_time: "10:00:00",
timezone: "Central Time (US & Canada)"
私がやりたいのは、これら3つの要素をUTCとしてデータベースに保存される単一の日付に解析することです。この場合、UTCタイムゾーンになったら開始時間に7時間を追加します。したがって、保存された時間は、受信した中央時間ではなくUTCとしてDBに格納されると、17:00になります。
私は日付を解析するためにこのようなことを試みました:
ActiveSupport::TimeZone[timezone].at DateTime.strptime("{ 2012-04-09 20:00:00 }", "{ %Y-%m-%d %H:%M:%S }").to_i
ただし、%Zを使用して結果の時間にタイムゾーンを組み込むことはできません。解析されないか、時刻が中部標準時ではなくUTCとして解釈されます。したがって、私の質問は、保存されている実際の日付/時刻の値を変更せずに、日付文字列を特定のタイムゾーンに強制する方法です。将来のタイムゾーン変換が正確になるように、文字列を解析して、正しいタイムゾーンを含む日付/時刻オブジェクトにその時点でを解析できるようにします。私はすべてを見てきたが、これを行う方法を見つけることができません。これは奇妙なことです。これは、HTMLフォームから入力された日付で一般的なことのように見えるためです。助けてくれてありがとう。
%Z
は、タイムゾーン名を指定する正しい方法です。以下を試しましたか?
date_and_time = '%m-%d-%Y %H:%M:%S %Z'
DateTime.strptime("04-15-2010 10:00:00 Central Time (US & Canada)",date_and_time)
これを試して:
zone = "Central Time (US & Canada)"
ActiveSupport::TimeZone[zone].parse("2013-04-03 17:47:00")
String#in_time_zone
(レール4+)個人的にはString#in_time_zone
:
>> '22.09.1986 10:30'.in_time_zone('Central Time (US & Canada)')
# => Mon, 22 Sep 1986 10:30:00 CDT -05:00
これは、指定されたタイムゾーンに文字列内の日付と時刻を解析します。
私はついにこれを行うための汚い、しかし決定的な方法を見つけました。
最初に、プレーンRuby Time.strptimeを次のように使用して文字列を解析します。
time = Time.strptime('12 : 00 : PM', '%I : %M : %p')
この方法では、解析された時間を取得できますが、まだ正しいタイムゾーンではありません。それを修正するには、時間を文字列形式に変換し、標準のActiveSupport :: TimeZone#parseで解析しましょう
Time.zone.parse(time.to_s)
結果は、正しいタイムゾーンに解析された時間を持つActiveSupport :: TimeWithZoneです。
このようにする必要がある理由は、ActiveSupport :: TimeZoneもActiveSupport :: TimeWithZoneもstrptimeメソッドをサポートしないためです。したがって、タイムゾーン情報を持たないcore Ruby strptimeでTimeを解析し、ActiveSupportオブジェクトで受け入れ可能な形式に変換してから、再度解析する必要があります。
これが私が思いついた方法です。最もきれいではありませんが、機能します。指定した形式を使用して文字列を解析し、Time.zone.parse
が必要とすることがわかっている形式に変換できるようにします。
class ActiveSupport::TimeZone
def strptime(time, format='%m/%d/%Y')
formatted = Time.strptime(time, format).strftime('%Y-%m-%d %T')
parse(formatted)
end
end
次に、別の質問で言及されたようなことを、指定された形式で行うことができます:
zone = "Central Time (US & Canada)"
ActiveSupport::TimeZone[zone].strptime('2013-04-03', '%Y-%m-%d')
または、すでにタイムゾーンが設定されている場合:
Time.zone = "Central Time (US & Canada)"
Time.zone.strptime('01/13/2006')
ほとんどの場合、ユーザー入力は%m/%d/%Y
のデフォルト形式を使用しているためです。これをニーズに合わせてカスタマイズするか、iso8601(%FT%T%z
)と思われるDateTime
が使用するデフォルトの形式を使用できます。
特定の日付形式をUTCに変換します。
ActiveSupport::TimeZone['UTC'].parse(Time.strptime('01/24/2019T16:10:16', "%m/%d/%YT%H:%M:%S").asctime)
DateTimeに日付文字列を取得させ、日付文字列の値を変更せずにUTC以外のタイムゾーンをアタッチするには、これを使用します。簡単で、うるう日に壊れません:)
xx = DateTime.strptime("9/1/15 #{object.time_zone}", "%m/%d/%Y %Z")