为什么 Time.parse 在 Rails 4 和 5 中失败,但在 Rails 3 中没有失败,因为日期字符串在日期和时间之间有 space?

Why does Time.parse fail in Rails 4 and 5 but not in Rails 3 for date strings with a space between the date and time?

在调查我 运行 将旧的 Rails 3 应用程序升级到 Rails 4 后遇到的错误时,我注意到当此日期字符串包含space,但在删除 space 时解析正确:

在 Rails 3.3.33.5:

Time.parse "12/13/2016 3:11 PM"
=> 2016-12-13 15:11:00 -0500

但在 Rails 4 和 5 中:

Time.parse "12/13/2016 3:11 PM"
ArgumentError: argument out of range
from /Users/diego/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/time.rb:302:in `local'

但是如果我删除日期和时间之间的 space 它会起作用:

Time.parse "12/13/20163:11 PM"
=> 2016-12-13 15:11:00 -0500

前一个也适用于 Rails 3. 我很困惑 Rails 的两个版本之间发生了什么,当日期之间有 space 时破坏了时间解析和时间。有什么想法吗?

作为一种解决方案,因为我需要向后兼容,所以我正在拯救 ArgumentError 并将 space 从日期字符串中 gsubbing 并重试。对此有更好的解决方案吗?

两个示例都是在 Ruby 2.2.5

中完成的

显然,在 Rails 4 及更高版本中,该字符串被解释为 dd/mm/yyyy(因为它 应该 ,如果你问我的话。见鬼去吧mm/dd/yyyy).

但如果您需要,正确的解决方案是指定格式,而不是 gsub 随机空格!

Time.strptime "12/13/2016 3:11 PM", '%m/%d/%Y %H:%M %p'
=> 2016-12-13 15:11:00 -0500

如果您确定日期是 mm/dd/yyyy 格式,您可以使用正则表达式切换 ddmm :

Time.parse '12/13/2016 3:11 PM'.sub(/(\d{2})\/(\d{2})\/(\d{4})/, '//')

关于 "why",情况是这样的:

Date._parse('12/13/2016 3:11 PM')
#=> {:hour=>15, :min=>11, :year=>2016, :mon=>13, :mday=>12}

对比:

Date._parse('12/13/20163:11 PM')
#=> {:hour=>15, :min=>11, :mon=>12, :mday=>13}

没有 space,年份将无法识别,12/13 将变为 mm/dd