我正在尝试用铁轨上的红宝石解析一个日期,这样我就可以从中获取月中和白天。
DateTime.parse("07/09") // Works
DateTime.parse("02/07/1975") // Works
DateTime.parse("08/26/1983") // Fails
DateTime.parse("04/28/1982") // Fails
DateTime.parse("10/17/1961") // Fails
为什么会失败?还有其他几个也失败了,没有我能看到的共同主题。
答案 0 :(得分:2)
在DateTime中尝试strptime
。它接收格式字符串。
答案 1 :(得分:2)
因为DateTime.parse("xx/xx/xxxx")
假设你给它格式DateTime("dd/mm/yyyy")
,即对美国以外的大多数世界都有意义的方式。最后三个例子不起作用,因为没有第26,28或17个月。请注意,您的第二个示例有效,但它可能无法满足您的想法:
DateTime.parse("02/07/1975").month # => 7
使用parse
代替strptime
,这样您就可以明确解析日期的格式:
DateTime.strptime("02/07/1975", "%m/%d/%Y")
DateTime.strptime("02/07/1975", "%m/%d/%Y").month # => 2
答案 2 :(得分:0)
你的问题源于Ruby有几个与日期和时间相关的类。其中包括:
每个类的功能和实现细节各不相同,但只有Time甚至会解析您的特定字符串。例如:
Date.new "08/26/1983"
# => ArgumentError: comparison of String with 0 failed
DateTime.new "08/26/1983"
# => ArgumentError: comparison of String with 0 failed
Time.new "08/26/1983"
# => 0008-01-01 00:00:00 -0500
显然,它不是公元0008年,因此您需要传递所选日期类理解的结构化日期。
您需要使用#strptime指定日期字符串的格式。例如:
Date.strptime('08/26/1983', '%m/%d/%Y').to_s
# => "1983-08-26"
DateTime.strptime('08/26/1983', '%m/%d/%Y').to_s
# => "1983-08-26T00:00:00+00:00"
然后,您可以使用所选类提供的格式化方法,例如DateTime#strftime或DateTime#rfc2822,以应用程序所需的任何方式格式化输出。
如果您可以访问GNU日期,则可以利用其更自由的解析。您可能仍会遇到语言环境问题,但一般来说GNU日期非常强大。例如:
%x(date -d 1983/08/26).chomp
# => "Fri Aug 26 00:00:00 EDT 1983"
%x(date -d 08/26/1983).chomp
=> "Fri Aug 26 00:00:00 EDT 1983"
我认为GNU日期不接受欧洲订单中的输入日期(例如dd/mm/yyyy
),但肯定会尊重输出中的区域设置。这对你的用例来说无关紧要,但对未来的访问者来说似乎值得一提。
答案 3 :(得分:0)
解析日期的重要一点是掌控一切。 Ruby的设计师做出了一个很好的决定,假设12/1/2000
是"DD/MM/YYYY"
格式的,因为它是为了共同利益,它只是让我们'美利安人错了,但是,然后,我们又有了奇怪的统治者,拼写“颜色“好笑,也开车走错了路。
因为我们知道我们的日期是奇怪的格式,所以我们可以使用Date.strptime
或DateTime.strptime
或Time.strptime
来指定日期的实际格式。使用'%m/%d/%Y'
领先的几个月,或'%d/%m/%Y'
为我们其他人......他们......无论哪个。
日期,日期时间和时间也有parse
方法,它可以处理许多不同的格式,但会在一个月与日期问题之间窒息。如果我相信我不会与'Merican vs. everyone-else日期相撞,我会将它们作为代码的起点。
如果您不知道日期数据的来源,一种策略是使用'%m/%d'
格式开始解析文件,并rescue
解析错误。如果你遇到一个,rewind
文件,retry
使用'%d/%m'
格式加载。
或者......为了获得真正的灵活性,请看看几乎疯狂的Chronic宝石。它仍然会超过%m/%d
与%d/%m
问题,但这无济于事。
软件无法对日期格式做出正确的决定,即使查看LOCALE设置或了解传入数据的经度/纬度坐标,因为数据可以来自任何地方。