DateTime.strptime can't parse date string - ruby

I don't understand why the following Ruby 2.4 code fails:
irb(main):006:0> require 'date'
=> false
irb(main):007:0> fmt = "%-m/%-d/%Y %-l:%M:%S %p"
=> "%-m/%-d/%Y %-l:%M:%S %p"
irb(main):008:0> DateTime.now.strftime(fmt)
=> "1/30/2018 7:42:44 AM"
irb(main):009:0> DateTime.strptime("1/30/2018 7:42:44 AM", fmt)
ArgumentError: invalid date
from (irb):9:in `strptime'
from (irb):9
from /usr/local/bin/irb:11:in `<main>'
irb(main):010:0>
The datetime format works when I format a date, but the same format string fails when I try to parse a date string in that format.

Its because strptime doesn't support the flags in the format you are using, have a look at http://ruby-doc.org/stdlib-2.4.2/libdoc/date/rdoc/DateTime.html#method-c-strptime

The error is because the format fmt you have provided doesn't match the DateTime string you have provided.
Change your format from
fmt = "%-m/%-d/%Y %-l:%M:%S %p"
into
fmt = "%m/%d/%Y %l:%M:%S %p"
Hope this helps.

Related

Ruby doesn't want to format string to date

I need to format a string to date:
date = DateTime.parse("05/15/2017")
formatted_date = date.strftime('%m/%d/%Y')
puts formatted_date
But I'm getting an error:
`parse': invalid date (ArgumentError)
And if I try to parse 15/05/2017 then it works.
How to parse 05/15/2017 into %m/%d/%Y format?
It is the first line that raises the error, because Date.parse doesn't know how to handle the string "05/15/2016". Use Date.strptime instead and tell Ruby how to read the string:
DateTime.strptime('05/15/2017', '%m/%d/%Y')
#=> #<DateTime: 2017-05-15T00:00:00+00:00 ((2457889j,0s,0n),+0s,2299161j)>

how to convert string to date object in ruby

I am getting a date as a string like below:
"September 1998"
I tried like Date.parse("September 1998"), but it did not work.
How do I convert it into a ruby date object which returns string in above format?
Date.strptime('September 1998', '%B %Y'). However, this will represent September 1st 1998, because date objects represent, well, dates.
You could use the chronic gem:
require 'chronic'
t = Chronic.parse('September 1998', :guess => true) #returns a Time object
=> 1998-09-01 00:00:00 -0700
t.to_date #convert to Date object
=> <Date: 1998-09-16 ((2451073j,0s,0n),+0s,2299161j)>
Chronic was created by Tom Preston-Werner, who also co-created Github.
Just prepend the missing "1 ":
str ="September 1998"
p Date.parse("1 " + str) # => #<Date: 1998-09-01 ((2451058j,0s,0n),+0s,2299161j)>

ruby parse date using strptime and strftime

So I'm parsing this string from AIX's errpt - to convert it into epoch - and it doesn't seem to be respecting the Hour and Minute part of the string.
So the string is: 1108095913 (MMDDHHMMYY) .. but when I do my strptime to convert it to a date object, and then format it how I want, it completely zero'd out my hour and minute.
Am I missing something?
irb(main):039:0> Date.strptime("1108095913", "%m%d%H%M%y").strftime('%m/%d/%y %H:%M')
=> "11/08/13 00:00"
You should use Time.strptime instead of Date method, Date removes hours and minutes
1.9.3-p429 :005 > Time.strptime("1108095913", "%m%d%H%M%y").strftime('%m/%d/%y %H:%M')
=> "11/08/13 09:59"
Use DateTime instead of Date:
irb(main):002:0> require 'date'
=> true
irb(main):003:0> DateTime.strptime("1108095913", "%m%d%H%M%y").strftime('%m/%d/%y %H:%M')
=> "11/08/13 09:59"
The reason is DateTime handles date and time, both and Date only handles date.
Hope this helps!

invalid date using Ruby 1.9.2

Why is 'time' being returned as an invalid date?
val = "9/22/2011 4:23 AM"
time = DateTime.parse(val).strftime("%Y-%m-%d %H:%M:%S").to_datetime
#at breakpoint: time = 2011-09-22T04:23:00+00:00 as a DateTime Object
#form_entry.storage_datetime = time # crashes here with invalid date
If it helps, I'm using gem mysql 2.8.1 and Ruby 1.9.2. Thanks
I got an ArgumentError on line two; couldn't create the DateTime object in the first place.
Try using strptime instead:
val = "9/22/2011 4:23 AM"
DateTime.strptime(val, "%m/%d/%Y %H:%M %p")
=> #<DateTime: 2011-09-22T04:23:00+00:00 (3536390423/1440,0/1,2299161)>

How do I create a Ruby date object from a string?

How do I create a Ruby date object from the following string?
DD-MM-YYYY
Date.parse('31-12-2010')
Alternatively Date#strptime(str, format).
Because in the USA they get the dates backwards, it's important not to simply use Date.parse() because you'll find 9/11/2001 can be 11 September 2001 in the USA and 9 November 2001 in the rest of the world. To be completely unambiguous use Date::strptime(your_date_string,"%d-%m-%Y") to correctly parse a date string of format dd-mm-yyyy.
Try this to be sure:
>irb
>> require 'date'
=> true
>> testdate = '11-09-2001'
=> "11-09-2001"
>> converted = Date::strptime(testdate, "%d-%m-%Y")
=> #<Date: 4918207/2,0,2299161>
>> converted.mday
=> 11
>> converted.month
=> 9
>> converted.year
=> 2001
For other strptime formats see http://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html
Also I always make sure I set my base timezone to :utc if my website is going to be handling any dates, and use Javascript on the client side to display local times.
You can use Time#parse.
Time.parse("20-08-2010")
# => Fri Aug 20 00:00:00 +0200 2010
However, because Ruby could parse the date as "MM-DD-YYYY", the best way is to go with DateTime#strptime where you can specify the input format.
If you have control over the format of the date in the string, then Date.parse works fine internationally with strings in YYYY-MM-DD (ISO 8601) format:
Date.parse('2019-11-20')
I find this approach simpler since it avoid having to specify the date format for the parser:
date1 = Time.local(2012, 1, 20, 12, 0, 0).to_date
Like this You can get time Object from a string like this:
t = Time.parse "9:00 PM"
=> 2013-12-24 21:00:00 +0530
t = Time.parse "12:00 AM"
=> 2013-12-24 00:00:00 +0530
But Ruby parsing this as a Date!
So you can use the column as a string.
add_column :table_name, :from, :string, :limit => 8, :default => "00:00 AM", :null => false
add_column :table_name, :to, :string, :limit => 8, :default => "00:00 AM", :null => false
And you can assign string object to the attribute,
r.from = "05:30 PM"
r.save
And parse the string for getting time object,
Time.zone.parse("02:00 PM")
Not necessary for this particular string format, but best string to time parsing utility I know is Chronic which is available as a gem and works for about 99.9% of usecases for human formatted dates/times.

Resources