【问题标题】:ArgumentError: invalid strptime format - `%m/%d/%y' work aroundArgumentError:无效的 strptime 格式 - `%m/%d/%y' 解决方法
【发布时间】:2017-04-11 21:47:17
【问题描述】:

我正在处理一个 sftp 导入错误,在该错误中我试图标记任何不正确的导入日期。有两种类型的日期可以取消。第一个是年份在未来或过去的时候;第二个是当实际月份和天数太高时。 (例如,13/20/1995 或 11/35/2000)

我正在使用strptime 并且对于关闭的日期,标记它们并将它们显示为特定消息。我遇到的问题是,使用我使用的strptime 格式,错误发生在我输入错误消息之前。

table_birth_dates = self.class.connection.execute("SELECT birth_date FROM #{temp_table_name}").values.flatten

table_birth_dates.map! do |date|
  birth_date = Date.strptime(date, '%m/%d/%Y')

  if birth_date.nil?
    month_day_error_message = 'Invalid Month/Day'
  elsif birth_date > Time.zone.today
    future_error_message = 'Year in Future'
  elsif birth_date.year < 1900
    past_error_message = 'Year too old'
  else
    birth_date
  end
end

错误发生在birth_date = Date.strptime(date, '%m/%d/%Y') 对于诸如10/3/1891, 之类的日期,它将显示为Sat, 03 Oct 1891. 但是,对于诸如33/33/2000 之类的混乱日期,它向我显示了一个错误(这是有道理的),但是我希望在我的条件下修复此错误。

有人知道我能做什么吗?

【问题讨论】:

  • 可以看看Date::valid_date?
  • 最简单的方法是挽救异常。在线救援将是 require 'date'; birth_date = Date.strptime(date, '%m/%d/%Y') rescue nil,如果 date 不代表有效日期,则将 birth_date 设置为 nil。您可以按照@orde 的建议使用Date::valid_date?,但要这样做,您需要解析出年、月和日:month, day, year = "11/35/2000".scan(/\d+(?=\/|\z)/).map(&amp;:to_i) #=&gt; [4, 35, 2000]; Date.valid_date?(year, month, day) #=&gt; false。 (在正则表达式中,(?=\/|\z) 是一个积极的前瞻。正则表达式只需 /\d+/ 就足够了。)
  • 嘿,谢谢@CarySwoveland 非常有用且简单的解决问题的方法。

标签: ruby date time strptime


【解决方案1】:

如果你想使用strptime,你唯一的选择就是挽救错误:

begin
  birth_date = Date.strptime(date, '%m/%d/%Y')
rescue ArgumentError => ex
  raise ex unless ex.message == 'invalid date'
  # handle invalid date
end

您可以将date 设置为,例如:invalid,然后如果您想将所有逻辑保留在那里而不是rescue 本身,则在条件中使用date == :invalid

【讨论】:

  • 我喜欢你使用ex 的方式。我们能否确信,在未来,'invalid date' 不会更改为其他措辞?更一般地说,您是否知道 Ruby 是否保证使用参数类返回的字符串描述不会改变?我一直认为字符串只是对编码人员有帮助,并没有看到它在代码中使用,但按照你的方式使用它是非常有意义的。
  • @CarySwoveland 不,这就是为什么人们应该编写测试来断言它的行为符合预期。如果以后的 Ruby 版本更改了消息,则测试将失败,并且可能会根据需要调整代码。
  • 好点,甚至在测试之前,ArgumentError 异常就会被抛出,这也涵盖了测试漏掉这个潜在问题的可能性。另一种观点是ArgumentError 异常只能在字符串不代表有效日期时引发,在这种情况下rescue ArgumentError 就足够了,并且不必担心"invalid date' 的变化。考虑到这只涉及一行简单的代码,这合理吗?
  • 我想知道为什么strptime(和其他日期/时间方法)在字符串不代表有效日期时不只返回nil。你或其他人知道为什么 Ruby 僧侣决定应该引发异常吗?
  • @CarySwoveland 不知道(尽管有些人会说例外比到处都是nils 更好)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
相关资源
最近更新 更多