ruby - Ruby 将 csv 日期格式化为无效日期(argumentError)
问题描述
我正在解析一个 csv 文件,我需要更改 dob 以匹配某种格式YYY-MM-DD
我不断收到这个错误,parse': invalid date (ArgumentError)
当它尝试解析这个日期时会发生"6/6/99"
我如何解决这个问题,所以我不会收到任何错误我有哪些日期?
csv 中所有日期的列表,我不确定上述日期之后的任何其他日期是否也会出错。
"12/12/2010"
"1/1/1988"
"2/2/1966"
"6/6/99"
"1/4/88"
"4/4/1948"
"1/6/1988"
"1/7/1988"
"1/8/88"
"1/9/88"
"1988-02-12"
"1-11-88"
"1/12/88"
"1/13/88"
我的代码
require 'csv'
require 'time'
require 'date'
def parse_csv
table = CSV.parse(File.read("input.csv", encoding: 'bom|utf-8' ), headers: true, col_sep: ",")
formatted = table.map(&:to_h)
formatted.each do |x|
if x["dob"] =~ /^\d{4}-\d{2}-\d{2}$/
p "correct"
else
parsed = Date.parse(x["dob"], "%Y-%m-%d")
p parsed
end
end
end
parse_csv
解决方案
从文档:
Date.parse
解析给定的日期和时间表示,并创建一个日期对象。
此方法不能用作验证器。如果输入字符串与有效格式不严格匹配,您可能会得到一个神秘的结果。应考虑尽可能使用
Date.strptime
代替这种方法。
您当前的实现实际上没有意义;它没有做你认为的那样:
Date.parse('6/6/99', "%Y-%m-%d")
#=> Date::Error: invalid date
这不是说“转换"6/6/99"
成” "1999-06-06"
,而是说“尝试解析"6/6/99"
成一个Date
对象(并且第二个参数基本上被忽略了!)。
如果您确信该日期应该是什么格式,那么(根据上面引用的文档!)您可以Date.strptime
尝试将其显式解析为这种格式。例如:
Date.strptime('6/6/99', "%m/%d/%y")
#=> #<Date: 1999-06-06 ((2451336j,0s,0n),+0s,2299161j)>
或者,如果您不确定前两个值应该代表月-日还是日-月,那么您需要在代码中明确处理此问题并适当地处理错误。
tl;博士:
Date.parse
对于任意输入不可靠;它只会对日期格式做出“最佳猜测”。不出所料,它至少在您抛出的一种模棱两可的格式中失败了。Date.strptime
当您知道您期望的格式时,是解析每个日期的正确方法。
推荐阅读
- ruby - Ruby 互斥锁与 GIL
- php - 子表的多对多关联和映射原则
- ruby-on-rails - 使用 Rails 的 highcharts(通过 LazyHighCharts),是否有 yDateFormat 的工具提示,用于在 Yaxis 上显示日期时间数据?
- distributed-system - aerospike 读取的强一致性 - 为什么他们需要政权编号?
- php - woocommerce 自定义运输方式未出现在运输区域
- python - 如何将我的雅虎财务输出保存到 excel 文件
- asp.net - .net IIS 表单身份验证始终拒绝访问,即使使用正确配置的 web.config
- django - 按多个条件过滤多对多关系中的对象
- functional-programming - 检查列表是否在球拍列表中包含大写或小写字母或数字
- java - 在 BottomNavigationView 中切换选项卡时出现延迟