How to convert MM / DD / YYYY during ruby?

I have a date in the format:

MM/DD/YYYY H:MMPM (not sure how to present PM)

How can I hide this in a Ruby date and time representation?

+5
source share
4 answers

You can send this line directly to Time.parse like this:

 2.0.0-p247 :001 > require 'time' => true 

Before Ruby 1.9:

 2.0.0-p247 :002 > Time.parse("12/1/2014 5:55PM") => 2014-12-01 17:55:00 -0500 

After Ruby 1.9

 2.0.0-p247 :002 > Time.strptime("12/1/2014 5:55PM","%m/%d/%Y %I:%M%p") => 2014-12-01 17:55:00 -0500 
+8
source

Do not use the parse method or anything on it for this.

In the USA, we use “MM / DD / YYYY”, but Ruby, which has a more universal bent, assumes “DD / MM / YYYY”, which can cause a lot of crashes if the day was> 12. It will also change the values ​​of the day and month.

If today is January 2, 2000, parse will receive the day / month ago in the date strings in the USA:

 DateTime.parse('1/2/2000 12:00AM') # => #<DateTime: 2000-02-01T00:00:00+00:00 ((2451576j,0s,0n),+0s,2299161j)> 

If the date is December 31, 2000, parse will break:

 DateTime.parse('12/31/2000 12:00AM') # => # ~> from -:4:in `<main>' # ~> -:5:in `parse': invalid date (ArgumentError) # ~> from -:5:in `<main>' 

Ruby assumes the first day:

 DateTime.parse('31/12/2000 12:00AM') # => #<DateTime: 2000-12-31T00:00:00+00:00 ((2451910j,0s,0n),+0s,2299161j)> 

Attempting to get around this situation by sniffing a date string will fail. The only way to make sure you can parse the date strings correctly is to know the date format used by the user or the software that generated the string, or always use ISO-based strings that are defined as a specific format.

Instead, give up the convenience of guessing something and tell Ruby which format to use:

 require 'date' DateTime.strptime('12/31/2000 12:00AM', '%m/%d/%Y %H:%M%p') # => #<DateTime: 2000-12-31T00:00:00+00:00 ((2451910j,0s,0n),+0s,2299161j)> 
+6
source

In rails, you can simply call .to_time into a string and .to_time it into a time object

 2.1.2 :002 > "12/1/2014 5:55PM".to_time => 2014-01-12 17:55:00 -0500 
+1
source

If you cannot rely on a format like ISO 8601, I like to be explicit when analyzing dates and times, as they can be represented in many ways. Using Time.strptime ,

 require 'time' str = "12/1/2014 5:55PM" d = Time.strptime(str, '%m/%d/%Y %I:%M%p') # d => 2014-12-01 17:55:00 +0000 

Notes for the time:

  • Use% i ("Hour of the day, 12-hour clock (01..12)"), not% H (which is within 24-hour time).
  • Use% M ("Minute Hour (00..59)"), not% m (i.e. months).
  • Use% p ("Meridian Indicator (AM / PM)"), not% P (for "am / pm")

Time analyzed from above will have TZ 0 / UTC - a solution that could be worms is another problem, and it might be easiest to parse the original string with the offset turned on.

 tzoff = "-08:00" d = Time.strptime("#{str} #{tzoff}", '%m/%d/%Y %I:%M%p %z') d.localtime(tzoff) # move back to the right localtime # d => 2014-12-01 17:55:00 -0800 
0
source

Source: https://habr.com/ru/post/1200696/


All Articles