如何从rails hash更改日期值的格式?

时间:2015-03-12 17:59:01

标签: ruby-on-rails ruby hash

我有一个变量

values = []
records.map { |record|
  # record <Letter::History Letter_ID: 15, Asset_Code: "10042019/01/01", Frequency_Code: "Alpha", Due_Date: "2014-05-29">
  # record.attributes => {"Letter_ID"=>15,
                        # "Code"=>"10018001/01/01",
                        # "Frequency_Code"=>"Alpha",
                        # "Due_Date"=>Sat, 24 May 2014
                        # }
  values << record.attributes
}

我想将Due_Date的日期格式更改为2014-05-24

我有另一组hash返回

second_hash = {"Letter_ID"=>15, 
     "Code"=>"10018001/01/01",
      "Frequency_Code"=>"Alpha",
      "Due_Date"=>Sat, 24 May 2014
     }

所以我可以比较两个hash值,如

values.to_a == second_hash.to_a

由于Due_date格式returns false现在。

由于

4 个答案:

答案 0 :(得分:2)

您可以使用类Date中的方法或使用正则表达式的方法String#sub来执行此操作。

使用Date类方法

my_hash = {"Letter_ID"     =>15,
           "Code"          =>"10018001/01/01",
           "Frequency_Code"=>"Alpha",
           "Due_Date"      =>"Sat, 24 May 2014",
           "Sent_Date"     =>"Thu, 12 Mar 2015"}

require 'date'

my_hash["Due_Date"] = Date.parse(my_hash["Due_Date"]).strftime('%Y-%m-%d')
  #=> "2014-05-24" 

my_hash
  #=> {"Letter_ID"=>15, "Code"=>"10018001/01/01", "Frequency_Code"=>"Alpha",
  #    "Due_Date"=>"2014-05-24", "Sent_Date"=>"Thu, 12 Mar 2015"}  

这里我们首先使用类方法Date::parse将现有日期字符串转换为日期对象:

date_obj = Date.parse(my_hash["Due_Date"])
  #=> Date.parse("Sat, 24 May 2014")
  #=> #<Date: 2014-05-24 ((2456802j,0s,0n),+0s,2299161j)>

现在使用Date#strftime"Due_Date"的值设置为date_obj转换为所需的格式:

my_hash["Due_Date"] = date_obj.strftime('%Y-%m-%d')
  #=> "2014-05-24"

如果您希望要求"Due_Date"的值符合给定的字符串格式,请使用Date#strptime代替parse

date_obj = Date.strptime(my_hash["Due_Date"], '%a, %d %b %Y')
  #=> #<Date: 2014-05-24 ((2456802j,0s,0n),+0s,2299161j)>

这种方法&#34;变异&#34; (改变)my_hash。如果我们希望返回一个新的哈希值,保持my_hash不变,请对my_hashmy_hash.dup)的副本进行操作。

使用String#sub

首先定义一个哈希,将月份缩写转换为数字的字符串表示,必要时用前导零填充:

h = %w[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec].
      zip(('01'..'12').to_a).to_h
  #=> {"Jan"=>"01", "Feb"=>"02", "Mar"=>"03", "Apr"=>"04",
  #    "May"=>"05", "Jun"=>"06", "Jul"=>"07", "Aug"=>"08",
  #    "Sep"=>"09", "Oct"=>"10", "Nov"=>"11", "Dec"=>"12"}

我们将使用这个正则表达式,它有三个捕获组,分别为日,月和年:

r = /\D*(\d{2}) ([A-Z][a-z]{2}) (\d{4})/

因为sub必须评估哈希h才能将月份转换为(此处)&#34; May&#34;到&#34; 05&#34;,我们必须使用sub的形式,使用哈希来计算替换字符串:

my_hash["Due_Date"] = my_hash["Due_Date"].sub(r) { "#{$3}-#{h[$2]}-#{$1}" }
  #=> "2014-05-24"

要使用命名组(v1.9 +),您可以这样做:

r = /\D*(?<day>\d{2}) (?<mon>[A-Z][a-z]{2}) (?<yr>\d{4})/

my_hash["Due_Date"].sub(r) do
  day = Regexp.last_match(:day)    #=> "24"
  mon = h[Regexp.last_match(:mon)] #=> "05"
  yr  = Regexp.last_match(:yr)     #=> "2014"
  "#{yr}-#{mon}-#{day}"
end
  #=> "2014-05-24"

答案 1 :(得分:1)

这样做

DateTime.parse(my_hash["Due_Date"]).strftime("%Y-%m-%d")

答案 2 :(得分:1)

你可以尝试

my_hash["Due_Date"] = my_hash["Due_Date"].strftime("%Y-%m-%d")

答案 3 :(得分:0)

我原以为strftime()已经证明适合这样的工作,并且参数%F在返回扩展日历日期时是正确的。

my_hash["Due_Date"].strftime(%F)

请参阅http://apidock.com/ruby/DateTime/strftime