Iは、任意時間帯成分と、それが有効なISO 8601時間である検証をユーザ入力のタイムスタンプを受信し、ユーザの設定した時間帯に応じてそれを解析できるようにする必要があります。ISO 8601タイムスタンプをユーザーのタイムゾーンで検証して解析するにはどうすればよいですか?
私は、Ruby 2.3の上のRails 4.2.6を使用しています。私は、ユーザー入力が有効なISO 8601時刻の表現であるかどうかを決定するためにArgumentError
例外を救うことができるようにTime.zone
(ActiveSupport::TimeZone
)はTime::iso8601
と同等の実装を持っているだろうと期待していました。それから、私は次のようなことをすることができます:
user_time_zone = 'America/Los_Angeles' # Would actually be from user's stored settings
params = {when: '2016-04-01T01:01:01'} # Would actually be from user input
# Would actually use Time::use_zone in around_action filter
Time.use_zone(user_time_zone) do
timestamp = Time.zone.iso8601 params[:when]
end
しかし、まあ、そのような方法はありません。そして私は同等のものを見つけることができません。
あいまいな日付を有効として扱うため、Time.zone.parse
は使用できません(例:Time.zone.parse '04/11/16' # => Tue, 16 Nov 0004 00:00:00 LMT -07:52
)。
Time.use_zone(user_time_zone) do
old_tz = ENV['TZ']
ENV['TZ'] = Time.zone.name
timestamp = Time.iso8601 params[:when] # => 2016-04-01 01:01:01 -0700
ENV['TZ'] = old_tz
end
しかし、これはこの方法が正しい感じていない環境変数をいじり、醜いであり、それと確かに:
私がこれまでに出てくることができました最善の選択肢でありますRailsのようなものではありません。 Railsの方法でユーザーのタイムゾーンに応じて時刻を検証して解析するにはどうすればよいですか?
//github.com/mojombo/chronic実際には、あなたのオリジナルのリビジョンは正しかったです。タイムゾーンは、時間を解析するときに考慮され、ユーザーのタイムゾーン設定に従って表示されますが、これは正しいです。異なるタイムゾーンで出力する必要がある場合は、#in_time_zoneを使用できます。正規表現を使用して2つのケースを区別しようとすると、エラーが発生しやすくなります(タイムスタンプが '2016-04-01T01:01:01Z'の場合など)。 – depquid
ああ、ありがとう、あなたは絶対に正しいです!私は答えをあまりに多く急いで、私のテストに十分注意を払わなかった。私は正規表現が理想的ではなく、必要でないとうれしいと同意する。答えの間違った部分を削除しました。 – BoraMa
優秀、これは私が必要としたものです。唯一の他の思考は 'begin..rescue'は、無効なタイムゾーンがTime.use_zone''に渡される場合など、他の 'ArgumentError's、区別するためにTime.iso8601''へのコールを中心に、より緊密に包むべきであるということです。 – depquid