Rails 使用时区参数和 DST 强制执行 DateTime 偏移

Posted

技术标签:

【中文标题】Rails 使用时区参数和 DST 强制执行 DateTime 偏移【英文标题】:Rails enforce a DateTime offset with a timezone param and DST 【发布时间】:2017-02-18 08:55:23 【问题描述】:

我刚刚遇到了一个 DateTime 字段的问题,该字段使用了错误的时区偏移量,我通常会观察到从同一个国家/地区提交的人(多么令人惊讶....来自 Internet Explorer)。我想知道这是否可能与即将在 10 月底结束的 DST 相关联,并且某些浏览器可能存在问题(尽管受影响的 DateTime 是在更改之前的 10 月 15 日左右)。

前端表单使用引导 datetimepicker(其底层实现依赖于 momentJS)。这是激活选择器和字段的 JS 的一小部分摘录,尽管我不确定它是否与此处相关

<div class="col-xs-4" id="appointment-time-start">
    <%= f.hidden_field :from %>
</div>
<script>
$('#appointment-time-start').datetimepicker(
        format: 'LT',
        defaultDate: "<%= model.from || (Time.now + 2.days) %>",
    );
</script>

为了避免这个问题,我要求用户也提交一个默认设置为巴黎时区的时区。

f.time_zone_select(:time_zone)

我应该如何使用这个时区来修改作为参数发送的其他日期?我有一个发送两个日期时间的简单约会表格,我需要修改它们以确保它们的偏移量与 time_zone 参数匹配(如果有效,夏令时额外 +1)。

我也想知道是否应该在控制器中或直接在模型中执行此操作。我的控制器正在做通常的事情,而我当前的模型看起来像(但现在我没有对 time_zone 做任何事情)

class Appointment
  include Mongoid::Document

  field :from, type: DateTime
  field :to, type: DateTime
  field :time_zone, default: 'Paris'

【问题讨论】:

尝试使用Time.zone.now,因为常规的 stdlib 时间类不支持 tz。 api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html @max 我试过 my_datetime.change(offset: ActiveSupport::TimeZone.new('Paris').formatted_offset) 但这给出了 +1 而不是 +2(因为预期的 DST) 【参考方案1】:

好吧,我在类似的问题上找到了this answer...我很惊讶没有更简单的助手可以做到这一点oO

def set_in_timezone(time, zone)
  Time.use_zone(zone)  time.to_datetime.change(offset: Time.zone.now.strftime("%z")) 
end

请注意,它仍然没有回答我是否应该在模型/控制器中执行此操作的问题。

【讨论】:

以上是关于Rails 使用时区参数和 DST 强制执行 DateTime 偏移的主要内容,如果未能解决你的问题,请参考以下文章

Rails 和 Postgres:迁移到 change_colomn 时出现错误“无法强制转换为没有时区的时间戳”

获取节点中特定时区的 UTC 偏移量和 DST 信息? [复制]

时刻时区和 DST

从一个本地时区到另一个本地时区的 Python 日期时间转换(+ 奖励 DST)

如何显示 dst 空闲时区偏移量?

如何编写单元测试以确保我的基于日期/时间的代码适用于所有时区以及有/无 DST?