Ruby Time.parse gives me out of range error - ruby-on-rails

I am using Time.parse to create a Time object from a string.
For some reason
Time.parse("05-14-2009 19:00")
causes an argument our of range error, whereas
Time.parse("05-07-2009 19:00")
does not
Any ideas?

If you know the format of the string use:
Time.strptime(date, format, now=self.now) {|year| ...}
http://www.ruby-doc.org/core-1.9/classes/Time.html#M000266
It will solve your problem and will probably be faster than Time.parse.
EDIT:
Looks like they took strptime from Time class, but it called Date.strptime anyway. If you are on Rails you can do:
Date.strptime("05-14-2009 19:00","%m-%d-%Y %H:%M").to_time
if you use pure ruby then you need:
require 'date'
d=Date._strptime("05-14-2009 19:00","%m-%d-%Y %H:%M")
Time.utc(d[:year], d[:mon], d[:mday], d[:hour], d[:min],
d[:sec], d[:sec_fraction], d[:zone])
See also: Date and Time formating issues in Ruby on Rails.

It's because of the heuristics of Time#parse.
And it's due to anglo-american formats.
With dashes '-' it expects mm-dd-yyyy, with slashes '/' it expects dd/mm/yyyy.
This behaviour changes intentionally in 1.9. to accomplish eur, iso and jp date standards.

My guess would be that its expecting the second part of the string (the 14) to be the month.
This link may help you parse it.

You probably do not need it to solve this problem but I still recommend checking out the natural language date/time parser Chronic, it has saved me a lot of work a couple of times.

It is probably expecting Day-Month-Year format, so your first value is trying to specify the 5th day of the 14th month.

Related

Get the days remaining from a methods rails

I have a starts_at attribute that is a standard DateTime data type. I want to take that time and the current Time to come up with 3 days remaining until event. This is my current method
def days_remaining
(Date.parse(starts_at) - Date.current).to_i
end
but this is giving me this error no implicit conversion of ActiveSupport::TimeWithZone into String
This seems pretty straight forward but I can't seem to figure it out.
Date.parse is expecting String argument, but starts_at is DateTime.
to_date method will convert datetime to date.
def days_remaining
(starts_at.to_date - Date.current).to_i
end
Though, I don't think this is 100% correct way to find remaining days.
Rails has distance_of_time_in_words method that can be used for this kind of thing. There's also the dotiw gem that offers more customisation of the output:
distance_of_time_in_words(Time.now, 2.weeks.from_now, only: :days)
def days_remaining
(starts_at.to_date...Date.current).to_a.count
end
This might be what you need. Creates a range of dates, convert to array, each entry is a day, then count those

strange behavior on datetime

I have the following record on my data base:
"availability_date" : ISODate("2014-09-29T15:45:00.000Z")
and I trying to get the differences between two datetime like this:
#minutes = (((#date_time.to_time) - (Time.now))/60).round
but the #date_time have the following value and I don't understand why???
"2014-09-29 17:45:00 +0200"
could someone help me please.
Thanks in advance
I don't think there is any problem, The datetime in #date_time is the same as in your database. The +0200 at the end means that it is written in a different timezone, here GMT +2, I guess. It is probably the time zone that your computer uses.
What is the result you expect ? Can you give an example ? And be sure to read the answer to In Ruby on Rails, what's the difference between DateTime, Timestamp, Time and Date?
Good luck.
Try to convert them to integer using to_i m this give you the number of seconds in unix time, the n it's probably more easy to do a calculation

Extract recognized date string passed to parse method in Chronic

I'd like to mimic the functionality of the Mac calendar quick event or Fantastical's quick entry. Using the Chronic gem, I can pass a string like:
"Today at 3pm"
=> 2014-01-24 15:00:00 -0600
Chronic parsing doesn't work if you pass in something like:
"Eat at Joes Today at 3pm"
=> nil
What I've done so far is use a simple regex to split a string at a word normally used to return a date with Chronic. The initial regex is simple:
scan(/(.+)(tomorrow{1}.+|in\s.+|next\s.+|today\s.+)/)
This returns an array with the "title", if you will, and the string I want to sent to Chronic to parse for me.
Two questions:
Is this really the best way to do this? I'd have to provide some mega regex to split whatever string I think my users will submit here.
Would hacking at Chronic be better? It's already parsing the dates for me, but my initial thought is no because if you pass Eat at Joes Today at 3pm to Chronic.parse, it'll return nil. It seems it doesn't recognize the part of the string for formatting the date in it's present form.
I wouldn't edit Chronic. Chronic's only function is to parse natural language date time, not other input. You might be interested in the Nickel gem here:
https://github.com/iainbeeston/nickel
This separates time from other language.
n = Nickel.parse("use the force on july 1st at 9am", Time.now)
n.message #=> "use the force"
n.occurrences.first.start_date #=> "20110701"

Ruby string to Date object

I have a Mongoid field that is of type Date. I'm having all sorts of trouble searching for documents against this specific field. I receive dates as a string in this format: 10/20/2013. I thought something like Date.parse("10/20/2013") or "10/20/2013".to_date would be good enough to let me do something like MyModel.find_by(datefield: date_result) but this is giving me a ton of ArgumentError out of range type issues.
What's the easiest way to turn "10/20/2013" into a simple Date object that I can use to query against databases?
You get this:
Date.parse("10/20/2013")
ArgumentError: invalid date
The problem is 10/20. Ruby is an international language, and the values 10 and 20 are somewhat ambiguous. In the U.S. the "standard" date format is "MMDDYYYY", or %m%d%Y in date parsing terms. The majority of the world uses a different standard though, "DDMMYYYY" or %d%m%Y. Ruby uses the second format, with day first.
Looking at the difference, it's easy to see why Date.parse would be confused and complain. 10 is a sensible day, but 20 is nonsense as far as a month, so Ruby rejects it.
You can fix this by forcing the pattern used for parsing:
Date.strptime('10/20/2013', '%m/%d/%Y')
# => #<Date: 2013-10-20 ((2456586j,0s,0n),+0s,2299161j)>
You can use strptime:
Date.strptime('10/20/2013', '%m/%d/%Y')
=> <Date: 2013-10-20 ((2456586j,0s,0n),+0s,2299161j)>
Read this a list of possible formats
Date.parse("10/20/2013")
=> ArgumentError: invalid date
to
Date.parse("20/10/2013")
=> Sun, 20 Oct 2013

Date conversion in rails

I am importing data from CSV inside Rails 3.2 and saving it to mongodb collection and everything works fine except the date field. The imported date format is DD/MM/YYY. Please how can I convert the imported date to YYYY-MM-DD?
Thanks
You could use date parsing like this:
Date.strptime('01/02/2003', '%d/%m/%Y').to_s #=> "2003-02-01"
Date.strptime creates a Date object from a string in the given format
Date#to_s returns it in the ISO 8601 format (i.e. YYYY-MM-DD)
But it depends on how big your CSV is - this would create a bunch of intermediate Date objects which would be a bit slower than a (slightly ugly) string indexing approach:
def reformat_date(date)
"#{date[6..9]}-#{date[3..4]}-#{date[0..1]}"
end
reformat_date('01/02/2003') #=> "2003-02-01"
Update
I was curious so I ran some quick benchmarks - the date parsing method was about 2.7 times slower than the string method (5.289s vs 1.981s for a million conversions, Ruby 1.9.3/Windows). YMMV.
You may need
require 'date'
Then use the following statement to parse the date:
d = Date.strptime('09/10/2012', '%d/%m/%Y')
Using the following examples will return the right format:
d.year #=> 2012
d.mon #=> 10
d.day #=> 9
d.strftime('%Y/%m/%d') #=> "2012/10/09"
Then save it to the database. I'm not familiar with mongodb, though, but I'm sure you know what to do.
For more information on date parsing you should visit http://www.ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/DateTime.html.

Resources