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

How to avoid from storing date objects in array in Ruby?

考虑以下代码:

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

此函数 return 数组格式如下:

[#<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)>]

但我希望它成为 return 格式的数组:

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

那我该怎么做呢?

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.strptime(e, '%dth %b %Y') 而不是 Date.parse(e),它的工作原理或多或少与 strftime 相反。参见 Date#strptime。它遵循一个模板 ('%dth %b %Y') 将原始字符串解释为日期。在 %d(天)之后将 th 添加到模板,它会将当前格式正确转换为日期对象:

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') }

我会这样做:

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"]

嗯,当你写的时候,你实际上是在存储 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')