Rails ActiveSupport 时间解析?

发布于 2024-07-10 05:25:34 字数 509 浏览 8 评论 0原文

Rails 的 ActiveSupport 模块使用许多方法扩展了内置的 ruby​​ Time 类。< /a>

值得注意的是,有 to_formatted_s 方法,它允许您编写 Time.now.to_formatted_s(:db) 来获取数据库格式的字符串,而不必到处写丑陋的 strftime 格式字符串。

我的问题是,有没有办法倒退?

像 Time.parse_formatted_s(:db) 之类的东西会解析数据库格式的字符串,返回一个新的 Time 对象。 这似乎是 Rails 应该提供的东西,但如果是的话,我找不到它。

是我找不到它,还是需要我自己写?

谢谢

Rails' ActiveSupport module extends the builtin ruby Time class with a number of methods.

Notably, there is the to_formatted_s method, which lets you write Time.now.to_formatted_s(:db) to get a string in Database format, rather than having to write ugly strftime format-strings everywhere.

My question is, is there a way to go backwards?

Something like Time.parse_formatted_s(:db) which would parse a string in Database format, returning a new Time object. This seems like something that rails should be providing, but if it is, I can't find it.

Am I just not able to find it, or do I need to write it myself?

Thanks

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

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

发布评论

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

评论(5

薄荷→糖丶微凉 2024-07-17 05:25:34

毕竟,看起来 ActiveSupport 确实提供了您正在寻找的解析方法(我也在寻找)! — 至少如果您尝试解析的字符串是标准的 ISO-8601 格式(:db 格式)日期。

如果您尝试解析的日期已经在您当地的时区,那么这非常简单!

 > Time.zone.parse('2009-09-24 08:28:43')
=> Thu, 24 Sep 2009 08:28:43 PDT -07:00

 > Time.zone.parse('2009-09-24 08:28:43').class
=> ActiveSupport::TimeWithZone

然后,可以轻松地将时区感知时间转换为 UTC

 > Time.zone.parse('2009-09-24 08:28:43').utc
=> 2009-09-24 15:28:43 UTC

或其他时区:

 > ActiveSupport::TimeZone.us_zones.map(&:name)
=> ["Hawaii", "Alaska", "Pacific Time (US & Canada)", "Arizona", "Mountain Time (US & Canada)", "Central Time (US & Canada)", "Eastern Time (US & Canada)", "Indiana (East)"]

 > Time.zone.parse('2009-09-24 08:28:43').utc.in_time_zone('Eastern Time (US & Canada)')
=> Thu, 24 Sep 2009 11:28:43 EDT -04:00

另一方面,如果您尝试解析的日期字符串采用 UTC 格式,则似乎没有任何方法可以将其 转换为 UTC 或其他时区。将其直接解析为 TimeWithZone,但我可以首先使用 DateTime.strptime 来解决这个问题...

如果您尝试解析的日期采用 UTC 格式,并且您希望它保持为UTC,你可以使用:

 > DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time
=> 2009-09-24 08:28:43 UTC

如果你试图解析的日期是UTC格式的,并且你希望它转换为你的默认时区,你可以使用:

 > DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time.in_time_zone
=> Thu, 24 Sep 2009 01:28:43 PDT -07:00

看起来它甚至可以解析其他格式,比如 Time 的奇怪格式#to_s 产生:

irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08').to_s(:db)
    => "2009-09-23 09:18:08"

irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08 EDT').to_s(:db)
    => "2009-09-23 06:18:08"

我印象深刻。

以下是来自 [http://api.rubyonrails.org/ 的更多示例classes/ActiveSupport/TimeWithZone.html][1]

  Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
  Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.at(1170361845)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
  Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00

更多参考文档链接:

It looks like ActiveSupport does provide the parsing methods you are looking for (and I was looking for too), after all! — at least if the string you are trying to parse is a standard, ISO-8601-formatted (:db format) date.

If the date you're trying to parse is already in your local time zone, it's really easy!

 > Time.zone.parse('2009-09-24 08:28:43')
=> Thu, 24 Sep 2009 08:28:43 PDT -07:00

 > Time.zone.parse('2009-09-24 08:28:43').class
=> ActiveSupport::TimeWithZone

and that time-zone-aware time can then easily be converted to UTC

 > Time.zone.parse('2009-09-24 08:28:43').utc
=> 2009-09-24 15:28:43 UTC

or to other time zones:

 > ActiveSupport::TimeZone.us_zones.map(&:name)
=> ["Hawaii", "Alaska", "Pacific Time (US & Canada)", "Arizona", "Mountain Time (US & Canada)", "Central Time (US & Canada)", "Eastern Time (US & Canada)", "Indiana (East)"]

 > Time.zone.parse('2009-09-24 08:28:43').utc.in_time_zone('Eastern Time (US & Canada)')
=> Thu, 24 Sep 2009 11:28:43 EDT -04:00

If the date string you're trying to parse is in UTC, on the other hand, it doesn't look like there's any method to parse it directly into a TimeWithZone, but I was able to work around that be first using DateTime.strptime...

If the date you're trying to parse is in UTC and you want it to stay as UTC, you can use:

 > DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time
=> 2009-09-24 08:28:43 UTC

If the date you're trying to parse is in UTC and you want it converted to your default time zone, you can use:

 > DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time.in_time_zone
=> Thu, 24 Sep 2009 01:28:43 PDT -07:00

It looks like it can even parse other formats, such as the strange format that Time#to_s produces:

irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08').to_s(:db)
    => "2009-09-23 09:18:08"

irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08 EDT').to_s(:db)
    => "2009-09-23 06:18:08"

I'm quite impressed.

Here are some more examples from [http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html][1]:

  Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
  Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.at(1170361845)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
  Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00

More documentation links for reference:

假面具 2024-07-17 05:25:34
ActiveSupport::TimeZone.new('UTC').parse('2009-09-23 09:18:08')
=> Wed, 23 Sep 2009 09:18:08 UTC +00:00
ActiveSupport::TimeZone.new('UTC').parse('2009-09-23 09:18:08')
=> Wed, 23 Sep 2009 09:18:08 UTC +00:00
不知所踪 2024-07-17 05:25:34

Rails 5 终于提供了 strptime!

value = '1999-12-31 14:00:00'
format = '%Y-%m-%d %H:%M:%S'
Time.zone.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 HST -10:00

ActiveSupport::TimeZone.all.sample.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 GST +04:00

Rails 5 finally provides strptime!

value = '1999-12-31 14:00:00'
format = '%Y-%m-%d %H:%M:%S'
Time.zone.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 HST -10:00

ActiveSupport::TimeZone.all.sample.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 GST +04:00
︶ ̄淡然 2024-07-17 05:25:34

我刚刚也遇到了这个问题,以上答案都不令我满意。 理想情况下,人们可以像 Time 一样使用 ActiveSupport::TimeZone 并以任意格式调用 .strptime 并返回正确的 TimeZone 对象。 ActiveSupport::TimeZone.strptime 不存在,所以我创建了这个猴子补丁:

 class ActiveSupport::TimeZone
    def strptime(str, fmt, now = self.now)
      date_parts = Date._strptime(str, fmt)
      return if date_parts.blank?
      time = Time.strptime(str, fmt, now) rescue DateTime.strptime(str, fmt, now)
      if date_parts[:offset].nil?
        ActiveSupport::TimeWithZone.new(nil, self, time)
      else
        time.in_time_zone(self)
      end
    end
  end

I just ran into this as well and none of the above answers were satisfactory to me. Ideally one could use ActiveSupport::TimeZone just like Time and call .strptime on it with any arbitrary format and get back the correct TimeZone object. ActiveSupport::TimeZone.strptime doesn't exist so I created this monkeypatch:

 class ActiveSupport::TimeZone
    def strptime(str, fmt, now = self.now)
      date_parts = Date._strptime(str, fmt)
      return if date_parts.blank?
      time = Time.strptime(str, fmt, now) rescue DateTime.strptime(str, fmt, now)
      if date_parts[:offset].nil?
        ActiveSupport::TimeWithZone.new(nil, self, time)
      else
        time.in_time_zone(self)
      end
    end
  end
謌踐踏愛綪 2024-07-17 05:25:34
>> "2009-09-24".to_date
=> Thu, 24 Sep 2009
>> "9/24/2009".to_date
=> Thu, 24 Sep 2009

效果很好,除非您的日期采用某种奇怪的格式。

>> "2009-09-24".to_date
=> Thu, 24 Sep 2009
>> "9/24/2009".to_date
=> Thu, 24 Sep 2009

Works great unless your date is in some weird format.

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