当我尝试 Date.parse 一个日期时,如何传递一个不是日期的字符串?

How can i by pass a string that is not a date when i'm trying to Date.parse a date?

我正在抓取一个网站,我正在尝试获取日期,例如书籍的发行日期。该网站并不总是为每本书提供日期,我有时会看到 "No date"、“????”、"Not yet released" 等。如果我尝试 运行 类似下面的内容并且没有收到错误,我该如何绕过它?我可以 运行 一个 if 声明,但我觉得它会变得混乱。

book = page.css(".date").text
date = Date.parse(book)

在Ruby中我们用rescue处理异常:

begin
  date = Date.parse("not a date")
rescue ArgumentError
  date = Date.today
end

p date
# => #<Date: 2016-05-28 ((2457537j,0s,0n),+0s,2299161j)>

在上面你也可以将 begin 块留空,在这种情况下 date 将被设置为 nil。此外,将赋值移到块外更符合习惯:

date = begin
  Date.parse("not a date")
rescue ArgumentError
  Date.today
end

您还可以使用 rescue 作为后缀或修饰符表达式:

date = Date.parse("not a date") rescue Date.today
p date
# => #<Date: 2016-05-28 ((2457537j,0s,0n),+0s,2299161j)>

但是请谨慎使用它,因为您无法指定异常类型,因此它可能会吞下您不希望它吞下的异常,这会使调试变得困难。

您可以改用 try catch。

try {
    date = Date.parse(book)
}catch(e){
    // set date as the default value.
}

chronic gem 提供了强大的日期解析功能,并将处理您将遇到的无效格式。

您可以安装它:

gem install chronic

或在您的 Gemfile:

gem "chronic"

您可以像这样解析示例中的日期:

book = page.css(".date").text
date = Chronic.parse(book)

如果日期无效,Chronic 将 return nil。然后,您所要做的就是确保您的代码是 nil-aware; 任何处理无效日期的 解决方案都必须 nil 感知,因此此要求并非 Chronic 独有。

The Chronic gem 有一段时间没有更新了,但它仍然具有相关性。它涵盖了如此多的日期解析基础,您可以在一段时间内将其用于报价。例如,您可能会发现各种格式的日期(例如“12/13/99”、“2002-10-04”、'May 13, 2007'),而 Chronic 可以毫不费力地处理这些日期。 Ruby 日期解析器默认仅支持有限数量的格式,您必须围绕它构建自定义代码以使其了解更多日期格式。

的已接受答案中,我展示了如何实现和使用 DateParser class 也缓存结果以提高性能;这值得一读,因为它在这种情况下肯定有帮助。