TZInfo識別子として受け取ったjs値をRails TimeZone名/キーにどのように変換しますか?
FROM:_"America/New_York"
_ JavaScript TZinfo検出から返されました
TO:Rails TimeZoneで使用される"Eastern Time (US & Canada)"
規則
または別の例:
_"Pacific/Honolulu"
_ =>変換=> _"Hawaii"
_
どちらも_ActiveSupport::TimeZone < Object
_マッピングで使用できますが、Railsはキーを使用します[例:ドロップダウンの"Eastern Time (US & Canada)"
]、検証、およびTime.use_zone()
への保存。
私が_ActiveSupport::TimeZone.us_zones
_について理解していることに基づくと、これは特にDayLightsの節約時間(Railsがうまく処理できるように聞こえます)の場合に重要であり、オフセットだけを一致させることはできません。 Rails TimeZone名でDBに保存されていない場合、検証は失敗し、ユーザーのプロファイル設定ページで_ActiveSupport::TimeZone.zones_map
_のドロップダウンリストと正しく一致しません。
これの目標は、ユーザーがサインアップ時にタイムゾーンを選択する必要がないこと、またはサインアップ後に設定でタイムゾーンを変更する必要がないことです。ブラウザはそれを検出し、サインアップ時にhidden_fieldに渡します。まれに、自宅や職場とは別の場所で申し込みをします。後でアカウント設定を手動で上書きできます。
Jsタイムゾーン検出を取り込もうとすると、一般的なギャップのようです。これは、返された情報をjsからRailsに渡して変換し、次にjsに戻してフォームのhidden_fieldに保存する方法の二次的な質問になる可能性がありますか?うまくいけば、私は質問を適切に組み立て、確かにRailsで少し緑色にしたので、これに対する簡単な解決策があるかもしれません...
助けてくれてありがとう!
-E
ActiveSupportTime.zoneドキュメント
http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html#method-i-parse
_MAPPING = {"Eastern Time (US & Canada)" => "America/New_York"
_
jsパッケージ化されたgem'temporal-Rails 'を使用してユーザーのタイムゾーンを検出します。
https://github.com/jejacks0n/temporal
見られるようにユーザーTime_Zone実装:
http://railscasts.com/episodes/106-time-zones-revised
* Devise&Deviseの使用-避けられない
_ <script>
$(function() {
var detected_zone = Temporal.detect();
console.log(detected_zone); // returns object
detected_zone = detected_zone.timezone.name;
console.log(detected_zone); // returns "America/New_York"
$('#user_time_zone').val(detected_zone); // ! need to convert this to Rails TimeZone name !
});
</script>
_
_ validates_inclusion_of :time_zone, in: ActiveSupport::TimeZone.zones_map(&:name)
_
_ <%= f.label :time_zone, label: "Time Zone" %><br />
<%= f.time_zone_select :time_zone, ActiveSupport::TimeZone.us_zones %>
_
Temporalには必要なロジックが含まれていますが、質問に答えるには:
Time.zone = ActiveSupport::TimeZone.new("America/New_York")
編集、私は私の答えが不完全だと思います。 「America/New_York」から「EasternTime(US&Canada)」に変更しますか?その場合、これが私が持っている最善の解決策です-誰かがより良いものを提供できるかもしれませんが。
ActiveSupport::TimeZone::MAPPING.select {|k, v| v == "America/New_York" }.keys.first
@ajbrausが提起した問題を解決するために、誰もが本当に求めていると私が信じている魔法は、どこでも議論されているのを見つけるのが奇妙に難しいものの1つである可能性があるワンライナーです。
timezone = ActiveSupport::TimeZone[TZInfo::Timezone.get('America/Vancouver').period_for_utc(Time.now.utc).utc_offset]
=> #<ActiveSupport::TimeZone:0x00007fc2baa6d900 @name="Pacific Time (US & Canada)", @utc_offset=nil, @tzinfo=#<TZInfo::TimezoneProxy: America/Los_Angeles>>
それ以外の場合、ActiveSupportのゾーンのDB全体を検索しようとすると、次のようになります。
ActiveSupport::TimeZone.all.find{ |tz| tz.tzinfo == ActiveSupport::TimeZone.find_tzinfo('America/Vancouver') }
=> nil
複雑さは次のように要約されます。