1

我正在尝试用 ruby​​ on rails 解析日期,以便从中获取月份和日期。

 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

那为什么会失败?还有其他几个也失败了,我看不到共同的线索。

4

4 回答 4

3

因为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
于 2013-03-26T14:40:20.083 回答
2

试试strptime日期时间。它接收格式字符串。

ruby-doc.org 上的文档

于 2013-03-26T02:16:43.500 回答
0

关于解析日期的重要事情之一是控制。Ruby 的设计师做出了一个很好的决定,假设12/1/2000"DD/MM/YYYY"格式,因为它是为了公共利益,它只是让我们“美国人错了”,但是,再说一次,我们有奇怪的统治者,拼写“颜色”很有趣,并且在错误的一边开车路也。

因为我们知道我们的日期是一种奇怪的格式,所以我们可以使用Date.strptimeorDateTime.strptimeTime.strptime来指定日期的实际格式。'%m/%d/%Y'用于前几个月,或'%d/%m/%Y'用于我们其他人......他们......无论哪个。

Date、DateTime 和 Time 也有parse方法,它能够处理许多不同的格式,但会在一个月与一天的问题上窒息。如果我确信我不会与“美国与其他所有人约会”发生冲突,我会将它们用作代码中的起点。

如果您不知道日期数据的来源,一种策略是使用'%m/%d'格式和rescue解析错误开始解析文件。如果您遇到一个,这很可能rewind是文件和retry使用'%d/%m'格式的负载。

或者......为了真正的灵活性,看看几乎疯狂的慢性宝石。%m/%d它仍然会在vs.问题上绊倒%d/%m,但这无济于事。

即使通过查看 LOCALE 设置或知道传入数据的经度/纬度坐标,软件也无法对日期格式做出正确的决定,因为数据可以来自任何地方。

于 2013-03-26T15:45:48.557 回答
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#strftimeDateTime#rfc2822,以应用程序需要的任何方式格式化输出。

改用 GNU 日期

如果您可以访问 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 date 接受欧洲顺序的输入日期(例如dd/mm/yyyy),但肯定会在输出中尊重语言环境。这对您的用例来说并不重要,但对于未来的访问者来说似乎值得一提。

于 2013-03-26T15:19:11.663 回答