如何避免在Ruby中将日期对象存储在数组中?

时间:2018-11-02 13:18:12

标签: ruby datetime-format

考虑以下代码:

dates = ["20th OCT 1232", "6th JUN 2019", "23th AUG 2017", "9th JAN 2015"]

def reformateDate(dates)
    ans = []
    dates.length.times do |i|
        ans << (DateTime.parse(dates[i], '%d %b %Y').to_date)
    end
    ans
end

此函数以以下格式返回数组:

[#<Date: 1232-10-20 ((2171339j,0s,0n),+0s,2299161j)>, #<Date: 2019-06-06 ((2458641j,0s,0n),+0s,2299161j)>, #<Date: 2017-08-23 ((2457989j,0s,0n),+0s,2299161j)>, #<Date: 2015-01-09 ((2457032j,0s,0n),+0s,2299161j)>]

但是我希望它以这种格式返回数组:

["1232-10-20","2019-06-06","2017-08-23","2015-01-09"]

那我该怎么做?

3 个答案:

答案 0 :(得分:4)

dates.map { |e| Date.parse(e).strftime('%Y-%m-%d') }
#=> ["1232-10-20", "2019-06-06", "2017-08-23", "2015-01-09"]

根据需要更改模板'%Y-%m-%d',请参见Date#strftime


从Cary Swoveland获得明智的建议。

您可以使用Date.parse(e)代替Date.strptime(e, '%dth %b %Y'),它的工作原理与strftime相反。参见Date#strptime。它遵循一个模板('%dth %b %Y')来将原始字符串解释为日期。在th(天)之后将%d添加到模板中,它将正确地将当前格式转换为日期对象:

Date.strptime("20th OCT 1232", '%dth %b %Y') #=> #<Date: 1232-10-20 ((2171339j,0s,0n),+0s,2299161j)>

但是,如果日期是'1st OCT 2018''23rd OCT 2018'怎么办?该模板不匹配,因为它希望找到th而不是strd

要成为普通后缀不可知,请使用方法String#sub

"20th OCT 1232".sub(/(?<=\d)\p{Alpha}+/, '') #=> "20 OCT 1232"

因此,将所有部分混合在一起,确保安全的最佳解决方案应该是:

dates.map { |e| Date.strptime(e.sub(/(?<=\d)\p{Alpha}+/, ''), '%d %b %Y').strftime('%Y-%m-%d') }

答案 1 :(得分:2)

好吧,您实际上是在编写时存储Date对象的:

ans << (DateTime.parse(dates[i], '%d %b %Y').to_date)

这有两个问题:首先,括号不执行任何操作,因此您可以删除它们。其次,您要做的是将字符串解析为DateTime对象,然后将其转换为Date对象。不太确定为什么要这么做,但是我认为这是一个错误。如果要临时使用DateTime对象将其转换为字符串,请考虑使用strftime,它将使用DateTime对象并将其转换为具有特定格式的字符串。看起来像这样:

ans << DateTime.parse(dates[i], '%d %b %Y').strftime('%Y-%m-%d')

答案 2 :(得分:1)

我会做这样的事情:

require 'date'

def reformat_date(dates)
  dates.map { |date| Date.parse(date).to_s }
end

dates = ["20th OCT 1232", "6th JUN 2019", "23th AUG 2017", "9th JAN 2015"]
reformat_date(dates)
#=> ["1232-10-20", "2019-06-06", "2017-08-23", "2015-01-09"]