为什么 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
格式,您可以使用正则表达式切换 dd
和 mm
:
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
。
在调查我 运行 将旧的 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
格式,您可以使用正则表达式切换 dd
和 mm
:
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
。