Reputation: 4636
I have a Variable
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
}
I want to change the date format of Due_Date
to 2014-05-24
I have another set of hash
that returns
second_hash = {"Letter_ID"=>15,
"Code"=>"10018001/01/01",
"Frequency_Code"=>"Alpha",
"Due_Date"=>Sat, 24 May 2014
}
So I can compare the two hash
value like
values.to_a == second_hash.to_a
Because of the Due_date
format it returns
false
now.
Thanks
Upvotes: 0
Views: 1880
Reputation: 110725
You can do this by using methods from the class Date or the method String#sub with a regular expression.
Using Date
class methods
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"}
Here we first use the class method Date::parse to convert the existing date string to a date object:
date_obj = Date.parse(my_hash["Due_Date"])
#=> Date.parse("Sat, 24 May 2014")
#=> #<Date: 2014-05-24 ((2456802j,0s,0n),+0s,2299161j)>
Now use Date#strftime to set the value of "Due_Date"
to date_obj
converted to the desired format:
my_hash["Due_Date"] = date_obj.strftime('%Y-%m-%d')
#=> "2014-05-24"
If you wish to demand that the value of the "Due_Date"
conforms to a given string format, use Date#strptime instead of parse
:
date_obj = Date.strptime(my_hash["Due_Date"], '%a, %d %b %Y')
#=> #<Date: 2014-05-24 ((2456802j,0s,0n),+0s,2299161j)>
This approach "mutates" (alter) my_hash
. If instead we wish to return a new hash, leaving my_hash
unchanged, operate on a copy of my_hash
(my_hash.dup
).
Using String#sub
First define a hash to convert month abbreviations to string representations of digits, padded with leading zeros where necessary:
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"}
We will use this regular expression, which has three capture groups, for day, month and year:
r = /\D*(\d{2}) ([A-Z][a-z]{2}) (\d{4})/
Because sub
must evaluate the hash h
in order to convert the month from (here) "May" to "05", we must use the form of sub
that employs a hash to compute the replacement string:
my_hash["Due_Date"] = my_hash["Due_Date"].sub(r) { "#{$3}-#{h[$2]}-#{$1}" }
#=> "2014-05-24"
To use named groups (v1.9+), you could do this:
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"
Upvotes: 2
Reputation: 5336
You can try
my_hash["Due_Date"] = my_hash["Due_Date"].strftime("%Y-%m-%d")
Upvotes: 1
Reputation: 73
I would have thought that strftime() would have proved suitable for such a job, and that parameter %F would be correct as it returns the extended calendar date.
my_hash["Due_Date"].strftime(%F)
See http://apidock.com/ruby/DateTime/strftime
Upvotes: 0
Reputation: 8132
do this
DateTime.parse(my_hash["Due_Date"]).strftime("%Y-%m-%d")
Upvotes: 1