ruby-on-rails - Rails Date#strptime 在 200 年之前错误地解析日期

标签 ruby-on-rails ruby

为什么 Rails 的 Date#strptime 将“13/08”解析为 200 年之前的 8 月 15 日或 8 月 14 日?

Date.strptime('13/08/99', '%d/%m/%Y')  #=> Thu, 15 Aug 0099
Date.strptime('13/08/100', '%d/%m/%Y') #=> Fri, 14 Aug 0100
Date.strptime('13/08/199', '%d/%m/%Y') #=> Tue, 14 Aug 0199
Date.strptime('13/08/200', '%d/%m/%Y') #=> Wed, 13 Aug 0200

最佳答案

总结:

如果您不使用 timecop gem,Date#strptime 似乎适用于 < 200 年。

如果您使用 timecop,Date#strptime 会被覆盖并使用 Time#to_date,这似乎会返回错误的年份 < 200 值。

简单的解决方案,要么:

  • 不要使用时间警察
  • 如果你使用 Date#strptime_without_mock_date 时间警察
  • 使用 Date.new + Time#strptime

更难的解决方案: 了解 Time#to_date 的实现有什么问题(参见 Stefan 的解释。)

[0] pry(main)> Time.local(99,8,13).to_date
=> #<Date: 0099-08-15 ((1757444j,0s,0n),+0s,2299161j)>
[1] pry(main)> Date.strptime('13/08/99', '%d/%m/%Y')
=> #<Date: 0099-08-13 ((1757442j,0s,0n),+0s,2299161j)>
[2] pry(main)> require 'timecop'
=> true
[3] pry(main)> Date.strptime('13/08/99', '%d/%m/%Y')
=> #<Date: 0099-08-15 ((1757444j,0s,0n),+0s,2299161j)>
[4] pry(main)> Date.strptime_without_mock_date('13/08/99', '%d/%m/%Y')
=> #<Date: 0099-08-13 ((1757442j,0s,0n),+0s,2299161j)>
[5] pry(main)> time = Time.strptime('13/08/99', '%d/%m/%Y')
=> 0099-08-13 00:00:00 +0053
[6] pry(main)> Date.new(time.year,time.month,time.day)
=> #<Date: 0099-08-13 ((1757442j,0s,0n),+0s,2299161j)>

关于ruby-on-rails - Rails Date#strptime 在 200 年之前错误地解析日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40582289/

相关文章:

ruby-on-rails - 更新破坏 Sass 框架 - 不兼容的单元 : 'px' and 'em'

ruby-on-rails - ActiveRecord::RecordNotFound - 无法找到 id=new 的联系人

java - 从 Java 执行 Ruby 脚本的运行时与 JRuby

javascript - Linux OpenOffice 自动化

ruby-on-rails - 在 ruby​​ 中迭代数组并使用给定字符串搜索匹配元素

ruby-on-rails - 如何通过 database.yml(或其他)在 ruby​​/sinatra 中引用 tiny_tds 连接?

javascript - 对象 [object Object] 没有方法 'nestedFields' - Awesome_nested_fields gem - Rails 3.2 jquery-ui-1.9.2

ruby-on-rails - buggy Rails 应用程序 : test or refactor?

mysql - rake 数据库 :create wrong location

ruby-on-rails - Ruby:堆栈级别太深(SystemStackError)