我正在使用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
关于我能做什么或我缺少什么的想法?谢谢!
答案 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