gpt4 book ai didi

ruby - 如何使用 DST 偏移量获取 time_zone_options_for_select?

转载 作者:行者123 更新时间:2023-12-05 01:48:50 24 4
gpt4 key购买 nike

ActionView::Helpers::FormOptionsHelper 提供 time_zone_options_for_select获取选择控件的选项列表,其中包括所有时区及其 UTC 偏移量。我遇到的问题是如何让它在夏令时生效时显示正确的偏移量?

例如,美国山地时间通常是 -7 UTC,但在夏季实际上是 -6 UTC。有没有办法让该列表正确反射(reflect)这一点?

最佳答案

长话短说

您收到的时区数据是“正确的”,因为 ActiveSupport::TimeZoneTZInfo::Timezone 实例不对当前日期做出假设,因此在这些对象的责任上下文中,对它们应用 DST 没有“意义”。

注意到这个问题是因为 time_zone_options_for_select 的默认模型, ActiveSupport::TimeZone,不幸的是在调用 #to_s 时返回偏移字符串,如果该位置当前正在观察 DST,则该字符串将不正确。无法修复选项中生成的字符串值,甚至无法删除它们的偏移量。

如果这是 Not Acceptable ,您将需要跳过使用 time_zone_options_for_select,并使用 options_for_select而是自己生成选项。

一些调查

time_zone_options_for_select 使用 ::ActiveSupport::TimeZone 作为默认的 model 参数,因此手动传递它不会改变您的结果。为了构造一个选择框的选项,该方法将构造一个格式为 [time_zone.to_s, time_zone.name] 的元组数组,目的是将其传递给更通用的 options_for_select 方法。 time_zone,在这种情况下,是 ::ActiveSupport::TimeZone 的实例。

这里的重要因素是,这个时区实例对象在概念上与“当前日期”的概念完全无关/分离。时区的定义(严格来说)与当前日期无关。我们可以像这样确认这个“不使用夏令时”的问题:

::ActiveSupport::TimeZone.all.find { |tz| tz.name == "Adelaide" }.utc_offset
=> 34200 # 9 hours and 30 minutes, in seconds

阿德莱德的非 DST 时区是 ACST(澳大利亚中部标准时间),即 GMT+9.5。目前(截至撰写本文时),阿德莱德采用 DST,这意味着他们采用 ACDT(澳大利亚中部夏令时),即 GMT+10.5。

::ActiveSupport::TimeZone.all.find { |tz| tz.name == "Adelaide" }.now.utc_offset
=> 37800 # 10 hours and 30 minutes, in seconds

这里的关键区别本质上就是我在上面概述的内容 - ActiveSupport::TimeZone 实例只是关心当前日期。该类本身是 TZInfo::DataTimezone 实例的便利包装器,它对当前日期有类似的意见 - 没有。

如果您注意到,在上面的第二个代码片段中,我们在调用 #utc_offset 之前对时区对象调用了 #now。这将返回一个 ActiveSupport::TimeWithZone 实例,其中包含有关时区和当前日期的信息 - 因此我们得到一个偏移量,它反射(reflect)了当前日期应包含 DST 偏移量这一事实.

因此,这里唯一的问题是在 ActiveSupport::TimeZone 实例的 #to_s 返回值中包含 UTC 偏移字符串在这种情况下有点误导.它包含在内是因为它是该时区的“基本”UTC 偏移量。

资源:

关于ruby - 如何使用 DST 偏移量获取 time_zone_options_for_select?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6297301/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com