加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 在Rails 3中如何解析ISO8601日期字符串以获取T

发布时间:2020-12-17 02:20:52 所属栏目:百科 来源:网络整理
导读:这是我的解决方案.有一个更紧凑的吗? time_from_client = "2001-03-30T19:00:00-05:00" = "2001-03-30T19:00:00-05:00" time_from_client.to_datetime = Fri,30 Mar 2001 19:00:00 -0500 timezone_offset = time_from_client.to_datetime.offset.numerator
这是我的解决方案.有一个更紧凑的吗?

> time_from_client = "2001-03-30T19:00:00-05:00"
 => "2001-03-30T19:00:00-05:00" 

> time_from_client.to_datetime
 => Fri,30 Mar 2001 19:00:00 -0500 

> timezone_offset = time_from_client.to_datetime.offset.numerator
 => -5 

> tz = ActiveSupport::TimeZone[timezone_offset]
 => (GMT-05:00) America/New_York

> tz.class
=> ActiveSupport::TimeZone

解决方法

不幸的是,这是不可能的,至少没有变得更聪明.

要了解为什么必须区分时区和UTC偏移:

>时区是指a specific region on earth,并且可以选择具有a period of DST.
> A UTC offset gives only the duration by which the given time is offset from UTC.

考虑从区域到偏移的映射:您还必须知道有问题的时间以及区域,以便决定是应用标准偏移还是日光偏移.

走另一条路要困难得多.再次只是偏移是不够的,因为我们不知道该偏移是指标准时间还是日光时间.但是这次我们有鸡/蛋问题:即使我们有时间,我们也需要知道区域,以便查看该时间是标准时间还是白天时间.但是,我们没有区域.

这是你的一个有用的例子,你正在使用Fri,2001年3月30日19:00:00,恰好是标准时间(EST),所以在第一次通过它看起来不错:

> time_from_client = "2001-03-30T19:00:00-05:00"
 => "2001-03-30T19:00:00-05:00" 


> time_from_client.to_datetime
 => Fri,30 Mar 2001 19:00:00 -0500 

> timezone_offset = time_from_client.to_datetime.offset.numerator
 => -5 

> tz = ActiveSupport::TimeZone[timezone_offset]
 => (GMT-05:00) America/New_York

我们有America / New_York.

但是看看如果我们跳到夏季时会发生什么,比方说,2001年6月30日19:00:00. time_from_client的偏移量组件现在为-04:00,这是纽约(EDT)的日光时间偏移量.

> time_from_client = "2001-03-30T19:00:00-4:00"
 => "2001-06-30T19:00:00-05:00" 


> time_from_client.to_datetime
 => Fri,30 Jun 2001 19:00:00 -0400

免责声明:下一步实际上不起作用,因为分子将向下舍入4/24到1/6,并且你将得到一个不正确的timezone_offset 1.因此我调整了你的实现并使用了utc_offset.

> timezone_offset = time_from_client.to_datetime.utc_offset
 => -14400

> tz = ActiveSupport::TimeZone[timezone_offset]
 => (GMT-04:00) Atlantic Time (Canada)

现在可以看到这个问题,而不是让美国/纽约的大西洋时间(加拿大).后者是标准偏移-04:00的区域名称之一,因为implementation of ActiveSupport::TimeZone[]只能使用标准的utc_offset找到,并且不知道日光.

如果你按照这个结论得出结论,你最终会得到以下反直觉的解析:

> tz.parse "2001-06-30T19:00:00-04:00"
 => Sat,30 Jun 2001 20:00:00 ADT -03:00

我假设在这里发生的是TimeWithZone看到这是六月,因此调整到大西洋日光偏移,-03:00.

值得注意的是,即使你可以考虑日光,并获得传递给ActiveSupport :: TimeZone []的标准偏移量,你仍然没有正确的区域,因为偏移到区域的映射不是一对一-一.

如下所示:

ActiveSupport::TimeZone.all.select { |z| z.utc_offset == -14400 }
=> [(GMT-04:00) Atlantic Time (Canada),(GMT-04:00) Georgetown,(GMT-04:00) La Paz,(GMT-04:00) Santiago]

这是我认为这是不可能的原因,除非您碰巧有原始ISO 8601字符串的位置信息.

顺便说一下,如果你采用这种方法,我推荐使用tzwhere Node.js库,它可以使用区域几何体做位置到区域查找.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读