更改数组元素中的日期格式

时间:2014-01-13 19:06:22

标签: ruby arrays date

我有一些数组元素(字符串)应格式化为日期(mm / dd / yyyy),当日期的日期部分为单个数字时,它们当前会导致问题。我假设同样的问题将发生在月份部分,虽然我只看到它与日期部分。我如何获取cells数组的元素,并将其格式化为格式为mm / dd / yyyy的日期,如果月份或日期是单个数字,则前导零。

数组将始终不同,但元素5,6和7将始终需要为日期。

我的阵列:

[1] [
    [0] "297",
    [1] "name",
    [2] "463",
    [3] "value",
    [4] "value1",
    [5] "12/8/2013",
    [6] "12/9/2013",
    [7] "12/9/2013"
],

5 个答案:

答案 0 :(得分:3)

要将您所说的格式更改为mm/dd/yyyy,请尝试以下操作:

sprintf("%02i/%02i/%4i", *(datestr.split("/").map {|i| i.to_i}))

答案 1 :(得分:2)

如果您希望将字符串转换为日期对象:

require 'date'

cells = []
cells[5] = "12/8/2013"
cells[6] = "12/9/2013"
cells[7] = "12/9/2013"

(5..7).each do |i|
  cells[i] = Date.strptime(cells[i], '%m/%d/%Y')
  puts "#{cells[i]} (#{cells[i].class} object)"
end

结果:

2013-08-12 (Date object)
2013-09-12 (Date object)
2013-09-12 (Date object)

答案 2 :(得分:1)

假设数组cells的日期始终为索引5到7,则以下内容将更新cells数组,使日期为mm/dd/yyyy格式:

require 'date'

cells[5..7] = cells[5..7].map { |date| Date.parse(date).strftime('%m/%d/%Y') }

答案 3 :(得分:1)

require 'date'

arr = ["297", "name", "463", "value", "value1", \
       "12/8/2013", "12/9/2013", "12/9/2013"]

FMT = '%m/%d/%Y'

arr.map! do |e|
  begin
    Date.strptime(e, FMT).strftime(FMT)
  rescue
    e
  end
end

arr # => ["297", "name", "463", "value", "value1", \
    #     "12/08/2013", "12/09/2013", "12/09/2013"]

strptime不代表格式为e的日期时,我只允许FMT引发异常,在这种情况下,arr的相应元素仍然存在不变。或者,可以使用类似if e =~ /^\d*\/\d*\/(\d*)$/...的内容。

可以改为使用Date.parse(e).strftime(FMT)(正如@OI所做的那样),因为m / d / y顺序没有变化,但在这种情况下我更喜欢strptime,因为它对要求的要求更高日期格式。

答案 4 :(得分:0)

您可能会遇到解析问题,更改字符串的格式根本无法修复。考虑一下:

require 'date'

date = Date.parse("12/8/2013") # => #<Date: 2013-08-12 ((2456517j,0s,0n),+0s,2299161j)>
date.day # => 12

当Date尝试以这种格式解析日期时,它假设某些东西对美国人来说不直观,但对世界其他地方有意义。在美国,我们假设日期为mm/dd/yyyy格式。世界其他地方的“正确思考”的人理解这意味着dd/mm/yyyy。面向世界其他地方的Ruby使用dd/mm/yyyy

要解决这个问题,我们必须更加明智地解析日期,并实际告诉Date使用什么:

date = Date.strptime("12/8/2013", '%d/%m/%Y') # => #<Date: 2013-08-12 ((2456517j,0s,0n),+0s,2299161j)>
date.day # => 12

或者:

date = Date.strptime("12/8/2013", '%m/%d/%Y') # => #<Date: 2013-12-08 ((2456635j,0s,0n),+0s,2299161j)>
date.day # => 8

如果您只想添加零填充字段,则可以采取以下几种方式:

array = [
  "297",
  "name",
  "463",
  "value",
  "value1",
  "12/8/2013",
  "12/9/2013",
  "12/9/2013"
].map { |e|

  if e[%r=(\d+)/(\d+)/(\d+)=]
    '%02d/%02d/%04d' % [$1, $2, $3]
  else
    e
  end

}
array # => ["297", "name", "463", "value", "value1", "12/08/2013", "12/09/2013", "12/09/2013"]

或者使用三元声明来获得更多隐匿性:

array = [
  "297",
  "name",
  "463",
  "value",
  "value1",
  "12/8/2013",
  "12/9/2013",
  "12/9/2013"
].map { |e|

  e[%r=(\d+)/(\d+)/(\d+)=] ? '%02d/%02d/%04d' % [$1, $2, $3] : e

}
array # => ["297", "name", "463", "value", "value1", "12/08/2013", "12/09/2013", "12/09/2013"]

如果要反转字段:

array = [
  "297",
  "name",
  "463",
  "value",
  "value1",
  "12/8/2013",
  "12/9/2013",
  "12/9/2013"
].map { |e|

  if e[%r=(\d+)/(\d+)/(\d+)=]
    '%02d/%02d/%04d' % [$2, $1, $3]
  else
    e
  end

}
array # => ["297", "name", "463", "value", "value1", "08/12/2013", "09/12/2013", "09/12/2013"]

或者使用三元线并交换搜索结果。

或使用scan

array = [
  "297",
  "name",
  "463",
  "value",
  "value1",
  "12/8/2013",
  "12/9/2013",
  "12/9/2013"
].map { |e|

  numerics = e.scan(/\d+/)
  case numerics.size
  when 3
    '%02d/%02d/%04d' % numerics
  else
    e
  end

}
array # => ["297", "name", "463", "value", "value1", "12/08/2013", "12/09/2013", "12/09/2013"]

如果你想反转字段:

'%02d/%02d/%04d' % [numerics[1], numerics[0], numerics[2]]

使用哪个取决于“引起问题”的意思。