Ruby:将特定CSV文件列中的日期转换为仅年份

时间:2018-04-19 18:33:49

标签: ruby csv date

我正在使用Ruby中的CSV文件,该文件包含多个包含日期的列。我尝试使用Ruby的所有列中的所有列只将日期转换为4位数年份。

示例CSV文件:

(编辑:忘记包含日期以引号括起来。)

name,birthdate,color,year1,fruit,year2
Joe,"1/1/1950",red,"1/18/1989",banana,"2/7/2003"
Joan,"2/4/2007",blue,"3/12/2010",peach,"4/10/2018"
John,"3/22/1979",yellow,"10/4/2009",plum,"11/17/2000"

我想离开"生日"列按原样,但我想改变" year1"和"第2年和第34年列只显示4位数年份,因此我得到以下结果:

预期结果:

name,birthdate,color,year1,fruit,year2
Joe,1/1/1950,red,1989,banana,2003
Joan,2/4/2007,blue,2010,peach,2018
John,3/22/1979,yellow,2009,plum,2000

我尝试将year1列声明为一个数组,然后通过&#34运行它;每个都执行#34;循环更改日期类型,但我最终得到" ArgumentError:无效日期"。我以为我接近答案但没有完全到达那里。

Ruby代码:

table = CSV.read('filename.csv', headers: true)

yr1 = p table['year1']

yr1.each do |date|
  Date.strptime(date, '%-m/-%d/%Y')
end

关于我能做什么或我缺少什么的想法?谢谢!

3 个答案:

答案 0 :(得分:0)

删除" no-padded"破折号,它会正常工作:

date = '2/7/2003'
Date.strptime(date, '%m/%d/%Y') #=> Fri, 07 Feb 2003

答案 1 :(得分:0)

我还有无效的日期ArgumentError,解决了:

date.gsub!(/\//, '-')
DateTime.strptime(date, '%m-%d-%Y')

答案 2 :(得分:0)

你似乎有几个问题,第一个是拼写错误:

yr1 = p table['yearl'] # note 'l' not '1'

在这里,您要求列名为 yearl ,最后一个字符为小写 L l )而不是数字 1

修复拼写错误仍会导致 ArgumentError(无效日期)问题,因为Date::strptime的文档声明:

  与strftime不同,

strptime不支持标志和宽度的规范。

所以我们需要删除标记破折号:

Date.strptime(date, '%-m/-%d/%Y')
# becomes
Date.strptime(date, '%m/-%d/%Y')

然后我们需要删除最后一个破折号,这可能是一个标志破折号。它不是标志,因为它位于百分号()之前,而是尝试匹配文字短划线:

Date.strptime(date, '%m/-%d/%Y') # this would work if `date` was "1/-18/1989"
# becomes
Date.strptime(date, '%m/%d/%Y')

所以现在你的新脚本看起来像:

require 'csv'
table = CSV.read('filename.csv', headers: true)

yr1 = p table['year1']

yr1.each do |date|
  p Date.strptime(date, '%m/%d/%Y')
end

并且有效。注意对p方法的2次调用可以删除,脚本仍然可以工作(但显然没有解析日期)。

将其写回文件是非常重要的:

require 'csv'
input = CSV.read('filename.csv', headers: true)

CSV.open("filename1.csv", "wb", headers: input.headers, write_headers: true) do |output|
  input.each do |row|
    row['year1'] = Date.strptime(row['year1'], '%m/%d/%Y').strftime('%Y')
    row['year2'] = Date.strptime(row['year2'], '%m/%d/%Y').strftime('%Y')
    # maybe even just these next lines for this small script, you might actually
    # need the Date object later though
    # row['year1'] = row['year1'].split('/').last
    # row['year2'] = row['year2'].split('/').last

    output << row
  end
end