我遇到了Date.parse方法的一个奇怪问题。
我尝试了几个ruby版本,它发生在所有版本中。以下测试在2.1.10版本中运行。
昨天我的所有考试都在通过,但今天他们开始失败了。原因是Date.parse调用开始引发异常。
如果系统日期是2017-01-31,它可以正常工作:
2.1.10 :002 > system('date')
Ter 31 Jan 2017 11:24:08 BRST
=> true
2.1.10 :003 > Date.parse("29%2F10%2F2015")
=> #<Date: 2017-01-29 ((2457783j,0s,0n),+0s,2299161j)>
但如果系统日期是今天,它就会失败:
2.1.10 :002 > system('date')
Qua 1 Fev 2017 11:24:27 BRST
=> true
2.1.10 :003 > Date.parse("29%2F10%2F2015")
ArgumentError: invalid date
from (irb):3:in `parse'
from (irb):3
from /Users/fernando/.rvm/rubies/ruby-2.1.10/bin/irb:11:in `<main>'
我可能可以通过使用另一种方法解析这个日期来解决这个问题,但我对它今天开始失败的原因感兴趣。
2017-02-01是ruby的特殊日期吗?
答案 0 :(得分:3)
Date.parse
是一种尝试使用多种启发法从给定字符串解析日期的方法,以便支持许多不同的格式而不指定实际格式。因此,除非格式清晰,否则Ruby总是可能得出与您不同的结论。
为了了解Ruby如何解析您的字符串,您可以使用
Date._parse("29%2F10%2F2015")
# => {:mday=>29}
正如您所看到的,Ruby能够从传递的字符串中获取29的日期,但不会获得任何其他信息。为了形成有效日期,Ruby替换当前日期中缺少的部分。现在,自2017年2月起只有28天,结果日期在此处无效,但在1月份有效。
然而,结果并不是你真正想要的。相反,尝试首先将您的日期转换为更容易解析的字符串,然后使用Eric Duminil的方法再次尝试这个问题的另一个答案:
require 'date'
require 'uri'
string = '29%2F10%2F2015'
Date.strptime(URI.unescape(string), '%d/%m/%Y')
# => #<Date: 2015-10-29 ((2457325j,0s,0n),+0s,2299161j)>
正如您所看到的,使用Date.strptime
,您可以指定已解析字符串的确切格式,因此可以确保它被正确解析或出错。
答案 1 :(得分:2)
%2F
是正斜杠(/
)
所以你需要先 decode
url-encoded string
> require 'open-uri'
#=> true
> string = "29%2F10%2F2015"
#=> "29%2F10%2F2015"
> date = URI::decode(string)
#=> "29/10/2015"
> Date.parse(date)
#=> #<Date: 2015-10-29 ((2457325j,0s,0n),+0s,2299161j)>
2017-02-01是ruby的特殊日期吗?
不,这不是特别的;)
> s = "2017-02-01"
> Date.parse(s)
#=> #<Date: 2017-02-01 ((2457786j,0s,0n),+0s,2299161j)>
答案 2 :(得分:2)
你有三个问题:
Date.parse
依赖系统日期来解析字符串。如果你知道你有哪种格式,你真的应该使用Date.strptime
:
require 'date'
require 'uri'
def parse_url_date(url_date)
Date.strptime(URI.unescape(url_date), '%d/%m/%Y')
end
puts parse_url_date("29%2F10%2F2015")
#=> 2015-10-29
puts parse_url_date("01%2F02%2F2017")
#=> 2017-02-01
答案 3 :(得分:0)
如果你知道你的日期&#34;是URL编码然后你必须首先对它们进行URL解码。使用URI.unescape()
,然后将其返回的值传递给Date.parse()
。
Date.parse(URI.unescape("29%2F10%2F2015"))