Rails 时区距偏移量

发布于 2024-11-10 05:37:57 字数 198 浏览 1 评论 0原文

所以看来 Rails 对时区有很好的支持,但我遇到了一个要求,我希望这个要求已经得到解决,但我只是没有在 api 中看到它。

我希望能够根据偏移量找到时区。原因是我连接到一个 api,它给我返回用户时区作为偏移量,并且不想重新发明轮子将该偏移量转换为 Rails TimeZone,以便应用程序的其余部分可以正确使用它。

有什么建议吗?感谢您的帮助!

So it seems rails has pretty nice support for timezones, but I've run into a requirement that I'm hoping has already been solved and I'm just not seeing it in the api.

I'd like to be able to find a TimeZone based on an offset. The reason being I'm hooking up to an api that gives me back the users time zone as an offset and don't want to necessarily reinvent the wheel turning that offset into a Rails TimeZone so the rest of the app can use it properly.

Any suggestions? Thanks for the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

狂之美人 2024-11-17 05:37:57

您可以使用 ActiveSupport::TimeZone 上的 [] 方法获取时区。您可以传递时区名称、小时偏移量或秒偏移量。例如:

ActiveSupport::TimeZone["America/Los_Angeles"]                              
 => (GMT-08:00) America/Los_Angeles
ActiveSupport::TimeZone[-8]                              
 => (GMT-08:00) America/Los_Angeles

但请记住,偏移量并不等于时区,因为多个时区在任何一天都可以具有相同的偏移量。

You can get a timezone using the [] method on ActiveSupport::TimeZone. You can either pass a timezone name, hour offset or second offset. For instance:

ActiveSupport::TimeZone["America/Los_Angeles"]                              
 => (GMT-08:00) America/Los_Angeles
ActiveSupport::TimeZone[-8]                              
 => (GMT-08:00) America/Los_Angeles

But keep in mind that an offset is not equivalent to a timezone since multiple timezones can be on the same offset on any one day.

请爱~陌生人 2024-11-17 05:37:57

所接受答案的问题在于,不幸的是,它不能处理两个不同时区具有相同 utc 偏移量的情况。

例如,-7 可能指亚利桑那州或丹佛,这是两个不同的时区(“美国/菲尼克斯”和“美国/丹佛”),因为亚利桑那州不遵守夏令时。

ActiveSupport::TimeZone[-7] 仅返回这两个有效时区之一。

在美国邮政编码数据库的稍微简单的情况下,我需要相同的功能,其中包括 UTC 小时偏移量和指示其是否参与夏令时的 Y/N 字段,因此该数据库中的美国西海岸邮政编码都具有“-8”和“Y”。

我找不到内置的 Rails 方法来执行此操作,因此我手动创建了一个查找哈希,其中键是 UTC 和 UTC 时间。 DST 字段相连,例如“#{utc}#{dst}”,值为时区名称。此方法也适用于 utc 偏移量,例如“5.5”(印度)。

在执行查找的方法中,给定 utc 和 dst 值,我指定一个默认时区(例如美国西海岸),以防哈希查找返回 nil,因为出现意外值,例如“-5N”(因为东海岸)海岸没有任何不应该发生的非 DST 状态)。

但同样的方法可以通过创建一个散列来全局应用,该散列代表所有可能的时区,其中包含夏令时的 Y 和 N 值。

class MyZip

HOUR_DST_TO_TIMEZONE_NAME = {
  "-5Y" => "Eastern Time (US & Canada)",
  "-6Y" => "Central Time (US & Canada)",
  "-7Y" => "Mountain Time (US & Canada)",
  "-7N" => "Arizona",
  "-8Y" => "Pacific Time (US & Canada)",
  "-9Y" => "Alaska",
  "-10N" => "Hawaii"
  }

def self.timezone_name_from_zip_hour_dst(utc, dst)
  key = "#{utc}#{dst}" 
  return HOUR_DST_TO_TIMEZONE_NAME[key] || MyZip.unknown_timezone_name
end
...

The problem with the accepted answer is that it unfortunately does not handle cases where two different timezones have the same utc offset.

For example -7 could be referring to Arizona or Denver which are two DIFFERENT times zones ("America/Phoenix" and "America/Denver"), because Arizona does not observe daylight savings time.

ActiveSupport::TimeZone[-7] returns only one of those two valid timezones.

I needed the same functionality in the slightly simpler case of a database of USA zipcodes which includes a UTC hours offset and Y/N field indicating if it participates in daylight savings time, so West coast USA zipcodes in this database all have "-8" and "Y".

I could not find a built-in Rails method to do it, so I manually created a lookup hash where the key is the UTC & DST fields catenated, eg, "#{utc}#{dst}" and the value is the timezone name. This method could work for utc offsets such as "5.5" (India) as well.

In the method that does the lookup is given the utc and dst values, I specify a default timezone (USA west coast for example) in the case where the hash lookup returns nil because an unexpected value such as "-5N" (since the east coast does not have any non-DST states that should never occur).

But the same method could be applied globally by creating a hash that represented all the possible timezone with both Y and N values for daylight savings time.

class MyZip

HOUR_DST_TO_TIMEZONE_NAME = {
  "-5Y" => "Eastern Time (US & Canada)",
  "-6Y" => "Central Time (US & Canada)",
  "-7Y" => "Mountain Time (US & Canada)",
  "-7N" => "Arizona",
  "-8Y" => "Pacific Time (US & Canada)",
  "-9Y" => "Alaska",
  "-10N" => "Hawaii"
  }

def self.timezone_name_from_zip_hour_dst(utc, dst)
  key = "#{utc}#{dst}" 
  return HOUR_DST_TO_TIMEZONE_NAME[key] || MyZip.unknown_timezone_name
end
...
迷爱 2024-11-17 05:37:57

有点黑客行为 - 但我正在使用 Google 的 Places API 来查找用户的位置,这给了我几分钟内的 UTC 偏移量。因此,我只想显示该位置的相关时区,因为一个 UTC 偏移量有很多时区。此外,Rails 的 TimeZone 帮助程序不会计算夏令时和其他动态偏移。因此,我添加了一个小时的加减值来获取所有相关的时区,而不希望让用户感到不知所措。

Google 以分钟为单位返回偏移量,但 Rails 需要以秒为单位。例如,对于加利福尼亚州的某个位置,我们的夏季偏移量(来自 Places API)为 -420 分钟。

offset = -420*60 # convert mins to secs
offset_range = (offset-3600)..(offset+3600)
timezones = ActiveSupport::TimeZone.all.select{|tz| offset_range.include?(tz.utc_offset)}

然后我将这些时区设置为 Rails 的 time_zone_select 中的优先区域。

Bit of a hack - but I was using Google's Places API to look up a location for a User, and that gave me the UTC offset in mins. So I wanted to present only the relevant time zones for that location, since there are many for one UTC offset. Further, Rails' TimeZone helper doesn't calculate Daylight Savings and other dynamic offsets. So I included one hour plus and minus to get all relevant time zones, without hopefully overwhelming the user.

Google returns the offset in minutes but Rails wants seconds. As an example, for a location in California we would have an offset (from Places API) of -420 mins for Summer.

offset = -420*60 # convert mins to secs
offset_range = (offset-3600)..(offset+3600)
timezones = ActiveSupport::TimeZone.all.select{|tz| offset_range.include?(tz.utc_offset)}

I then set these timezones as priority zones in Rails' time_zone_select.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文