从字符串中查找最接近的日期

时间:2013-09-15 07:10:09

标签: ruby datetime

我正在尝试将“Sep 11,Oct 31,Feb 28”等字符串转换为DateTime实例,作为屏幕抓取工具的一部分。使用DateTime.parse()除了数据经过多年时间之外还可以正常工作,并且天真(并且可能正确)返回当前年份的日期。

例如以下测试用例。

test "dateA convert next year" do
  TimeService.stubs(:now).returns(Time.new(2013, 12, 30, 9, 30))
  assert_equal(Date.new(2014, 1, 2), Extraction.dateA("Jan 2"))
end

我更新了我的方法以查看年份+ 1的日期,并返回最接近“现在” - 这样可以正常工作。然而,它感觉有点难看,我正在寻找一个更优雅的解决方案。

def Extraction.dateA(content)
  return_value = DateTime.parse(content)
  next_year = return_value.change(:year => return_value.year + 1)
  now = TimeService.now.to_i
  if (next_year.to_i - now).abs < (return_value.to_i - now).abs then
    return_value = next_year
  end
  return_value
end
  • TimeService.now只是一个返回当前时间以帮助进行存根的工具。
  • 请原谅我的红宝石,我是新手。

1 个答案:

答案 0 :(得分:1)

我认为这是按预期工作的,也允许上一年的最接近日期:

module Extraction
  def Extraction.date_a(content)
    parsed_date = DateTime.parse(content)
    now = DateTime.now
    dates = [ parsed_date, parsed_date.next_year, parsed_date.prev_year ]
    dates.min_by { |d| ( d - now ).abs }
  end
end

几点:

  • 将方法名称更改为date_a,只是一个与Java不同的Ruby约定。
  • 我在DateTime上使用了一些内置方法next_yearprev_year
  • 我使用时差指标和选定日期,其中包含三个候选日期的最小值(这是min_by所做的)。这比条件切换更简单,特别是需要考虑三个日期。

我原本忘了min_by,我不经常使用它,但它非常适合这个问题。

请注意,有一个病态案例 - “2月29日”。如果它在文本中正确显示,则其性质将定义哪一年有效,并且如果当前年份是例如,它将不会解析。 2015。