【问题标题】:Best way to get midnight on a specific day in a specific time zone in Rails在 Rails 中特定时区的特定日期获得午夜的最佳方式
【发布时间】:2016-11-23 00:42:30
【问题描述】:

我正在使用一个 Rails 应用程序,该应用程序以“YYYY-MM-DD”格式的字符串形式提供日期,我想知道将其转换为 TimeWithZone 对象的最佳方法是在特定时间设置为午夜zone,由数据库提供,也是String的形式。

基本上我想要这个:

"2016-06-01", "America/New_York" => 2016 年 6 月 1 日星期三 00:00:00 EDT -04:00

"2016-06-01", "Europe/Berlin" => 2016 年 6 月 1 日星期三 00:00:00 CEST +02:00

"2016-01-01", "America/New_York" => 2016 年 1 月 1 日星期五 00:00:00 EST -05:00

"2016-01-01", "Europe/Berlin" => 2016 年 1 月 1 日星期五 00:00:00 CET +01:00

现在我知道它绝对 不是只是 Date.parse(x).to_datetime.in_time_zone(y).beginning_of_day 因为对于“America/New_York”示例,这将分别产生“2016 年 5 月 31 日星期二 00:00:00 EDT -04:00”和“2015 年 12 月 31 日星期四 00:00:00 EST -05:00”,所以我考虑过通过添加来纠正它如果 utc_offset 为负数,则一天,所以我构建的方法基本上是这样的:

def midnight_in_time_zone(date_string, time_zone_string)
  time_with_zone = Date.parse(date_string).
    to_datetime.
    in_time_zone(time_zone_string).
    beginning_of_day
  
  time_with_zone += 1.day if time_with_zone.utc_offset < 0
  
  time_with_zone
end

这按我想要的方式工作,但感觉就像我正在以一种 hacky 的方式重新发明轮子,因为我想要做的似乎是一个基本功能,所以我想知道是否有内置方法我不知道我可以用它来使这更简单,或者是否有人知道这样做的更好方法。

【问题讨论】:

  • 理想情况下,您最初会使用DateTime 对象,这意味着您可以更轻松地获得最终结果。我过去不得不编写类似的代码,但不知道更简单的方法。
  • @Tass 有没有办法使用像“America/New_York”这样的标准名称来创建一个带有时区偏移的新 DateTime 对象?我知道可以使用像“-5”这样的字符串形式的偏移量,但是由于北美和欧洲大多数时区的夏令时会随着夏令时的变化而变化,没有它我想不出一个好的管理方法感觉更像是重新发明轮子,所以使用标准名称并让 Rails 确定偏移量将是理想的。
  • 说到夏令时,我刚刚意识到,如果我的“1 天”修正发生在 UTC 之后时区夏令时更改的那一天,那么结果将是晚上 11 点或凌晨 1 点,具体取决于变化的方向。
  • 我相信您正在寻找使用类似TZInfo gem 的东西。在我们的应用程序中,它作为至少几个其他 gem 的依赖项安装。您可以查看示例用法:github.com/tzinfo/tzinfo#example-usage
  • (我正在浏览我在工作中制作的一些自定义一次性脚本,看看是否可以为您提供示例。)

标签: ruby-on-rails date datetime timezone


【解决方案1】:

你可以试试这个:

def midnight_in_time_zone(date_string, time_zone_string)
   date_string.in_time_zone(time_zone_string)
end

如果time_with_zone.utc_offset的值小于0,这条线自动增加1天

示例结果:

#Your code puts
time_with_zone = Date.parse("2016-01-01").to_datetime.in_time_zone("America/New_York").beginning_of_day
#=> Thu, 31 Dec 2015 00:00:00 EST -05:00
#If you try this
date_string.in_time_zone(time_zone_string)
#=> Fri, 01 Jan 2016 00:00:00 EST -05:00

【讨论】:

  • 谢谢,但应该注意的是,您的解决方案适用于 Rails 4。我们的一些服务器仍在 Rails 3 上运行,但我想我可以对其进行调整,直到它们升级为止。
猜你喜欢
  • 2018-12-15
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多