Ruby-on-rails Rails ActiveSupport 时间解析?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/354657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 20:50:04  来源:igfitidea点击:

Rails ActiveSupport Time Parsing?

ruby-on-railsrubyparsingtimeactivesupport

提问by Orion Edwards

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

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

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

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

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.

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

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

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

Thanks

谢谢

回答by Tyler Rick

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 (:dbformat) date.

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

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

然后可以轻松地将时区感知时间转换为 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 directlyinto a TimeWithZone, but I was able to work around that be first using DateTime.strptime...

另一方面,如果您尝试解析的日期字符串是 UTC,则看起来没有任何方法可以将其直接解析为 TimeWithZone,但我能够首先使用 DateTime.strptime 解决该问题...

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

如果您尝试解析的日期是 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

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

如果您尝试解析的日期是 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

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

看起来它甚至可以解析其他格式,比如 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"

I'm quite impressed.

我很感动。

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

以下是 [ 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:

更多文档链接供参考:

回答by Leventix

ActiveSupport::TimeZone.new('UTC').parse('2009-09-23 09:18:08')
=> Wed, 23 Sep 2009 09:18:08 UTC +00:00

回答by vemv

Rails 5 finally provides strptime!

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

回答by Ben Mabey

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

我也遇到了这个问题,上面的答案都没有让我满意。理想情况下,可以使用ActiveSupport::TimeZonelikeTime.strptime以任意格式调用它并返回正确的TimeZone对象。 ActiveSupport::TimeZone.strptime不存在所以我创建了这个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

回答by eremite

>> "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.

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