Learner
Learner

Reputation: 4636

how to change the format of date value from rails hash?

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

Answers (4)

Cary Swoveland
Cary Swoveland

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

Gerry
Gerry

Reputation: 5336

You can try

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

Upvotes: 1

DasKapital
DasKapital

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

Paritosh Piplewar
Paritosh Piplewar

Reputation: 8132

do this

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

Upvotes: 1

Related Questions