Converting twitter post dates to datetime in rails - ruby-on-rails

I am trying to convert the twitter post dates into datetime objects but for some reason they are not converting correctly. If I do this:
d = '12:06 AM Oct 15th'
and
d = DateTime.parse(d)
or
Tweet.new :body => "test", :created_at => d
then the date ends up Sun Nov 15 00:06:00 -0500 2009. All dates are converting and containing the month of November. Am I totally missing something?

DateTime.parse expects the passed in string to be in a standard format. Since that is not the case with your strings, you'll have to use DateTime.strptime and pass it your string representation of date/time, along with the corresponding format string. In your case something like this should work:
d = DateTime.strptime '12:06 AM Oct 15th', '%H:%M %p %b %d'
d.to_s # => "2009-10-15T00:06:00+00:00"
You can check the documentation to see what each of the formatting directions means.

Always always always use the Chronic gem. Will solve all your problems when it comes to date/time parsing: http://github.com/mojombo/chronic

You might be able to get away with mangling it slightly and then using the parser:
s = '12:06 AM Oct 15th'
d = DateTime.parse(s.sub(/(\w\w\w) /, '\1'))
puts d.to_s
# => 2009-10-15T00:06:00+00:00

Related

Parsing date using strftime

I have a problem parsing dates taken in from scraping a website using Nokogiri. I scrape the datetime using
#date = h4.at('time[itemprop="startDate"]')[:datetime]
This gives me 2015-04-28 19:30:00 UTC, which is inserted into my date column, of type "datetime".
Using strptime I am trying to parse the date into a "dd/mm" format, and enter it into my Rails table:
Date.strptime(#date, "%Y-%m-%d %H:%M:%S %Z").strftime("%m/%d/%Y")
#event=Event.new
#event.date= #date
Any help would be very much appreciated.
Here's some code that might help:
require 'date'
require 'time'
date = Date.strptime('2015-04-28 19:30:00 UTC', "%Y-%m-%d %H:%M:%S %Z")
# => #<Date: 2015-04-28 ((2457141j,0s,0n),+0s,2299161j)>
date.strftime('%m/%d/%y')
# => "04/28/15"
Parsing into a Date object stores only the year, month and day information.
datetime = DateTime.strptime('2015-04-28 19:30:00 UTC', "%Y-%m-%d %H:%M:%S %Z")
# => #<DateTime: 2015-04-28T19:30:00+00:00 ((2457141j,70200s,0n),+0s,2299161j)>
datetime.strftime('%m/%d/%y')
# => "04/28/15"
time = Time.strptime('2015-04-28 19:30:00 UTC', "%Y-%m-%d %H:%M:%S %Z")
# => 2015-04-28 19:30:00 UTC
time.strftime('%m/%d/%y')
# => "04/28/15"
Parsing into a DateTime, or Time object captures all the information.
The error you're seeing is often caused by a date string in a format you don't expect. That often happens when you expect a value in 'mm/dd/yy' order, but actually receive one in 'dd/mm/yy' order. This happens because the US uses 'mm/dd/yy' and most of the rest of the world uses 'dd/mm/yy':
date = Date.strptime('2015-28-04', '%Y-%m-%d')
# ~> -:7:in `strptime': invalid date (ArgumentError)
or
date = Date.strptime('28-04-2015', '%m-%d-%Y')
# ~> -:7:in `strptime': invalid date (ArgumentError)
You can work around that by using some rescue statements to try several different formats.
You don't want to use parse because it'll assume 'dd/mm/yyyy' and will blow up with US dates, and is slower because it tries multiple formats before giving up. So, using fixed formats you expect is the way to go but you need to search for your various formats of date/datetime strings you'll expect to find and write format strings to match. And, since you're scraping pages, it's possible to find a LOT of bad/malformed values so program defensively.
You don't need strftime and you can parse the date with parse. Just convert the string to a Date object and assign that to your ActiveRecord attribute:
#event = Event.new
#event.date = Date.parse('2015-04-28 19:30:00 UTC')

Ruby on Rails invalid date error when parsing datetime string to convert to a different format

In my Rails App (Rails 2.3.14 and Ruby 1.8.7) I am trying to convert a datetime string into a different format to perform a search on my MySQL database but I am getting an invalid date error and I can't seem to figure out why, I've read a good few similar questions but I still can't seem to resolve the issue.
# check if filter contains a time stamp
if params[:sSearch].include?('/') and params[:sSearch].include?(':')
datetime = DateTime.strptime(params[:sSearch], "%Y-%m-%d %H:%M")
params[:sSearch] = datetime
end
Example scenario
04/11/13 16:14
should convert to
2013-11-04 16:14
I thought it might have been to do with the fact that the seconds aren't included in the front-end representation of the string as the precise datetime in the database table is 2013-11-04 16:14:52 so I included the seconds now but still getting the same error and I don't think that should matter since I am using the LIKE operand with wildcards on either side of the search term, so even without the seconds it should work.
You should use slashes in the format and replace %Y (four digit year) with %y (abbreviated two digit year) to get the desired result. Besides, the order of the date fields is reversed. The correct format would be:
"%d/%m/%y %H:%M"
I think you confused the purpose of strptime and strftime. Whereas the p in strptime stands for "parse" (make DateTime from String), the f in strftime stands for "format" (the other direction).
require 'date'
DateTime.strptime("04/11/13 16:14", "%Y-%m-%d %H:%M")
# ArgumentError: invalid date
DateTime.strptime("04/11/13 16:14", "%d/%m/%Y %H:%M")
#=> #<DateTime: 0013-11-04T16:14:00+00:00 ((1722836j,58440s,0n),+0s,2299161j)>
# Wrong! You do not want the year 0013, but 2013
DateTime.strptime("04/11/13 16:14", "%d/%m/%y %H:%M")
#=> #<DateTime: 2004-11-13T16:14:00+00:00 ((2453323j,58440s,0n),+0s,2299161j)>
# Correct
you can later convert it to the desired format with DateTime#strftime like this:
# parse the user input to a DateTime object
datetime = DateTime.strptime("04/11/13 16:14", "%d/%m/%y %H:%M")
# reformat it
params[:sSearch] = datetime.strftime("%Y-%m-%d %H:%M")
strptime converts the given string into a datetime object using the format given.
DateTime.strptime("04/11/13 16:14", "%m/%d/%y %H:%M").strftime("%Y-%m-%d %H:%M")
There is a problem with your template, try: DateTime.strptime("04/11/13 16:14", "%d/%m/%y %H:%M")

Is there an easy way to fetch year from a date string in ruby?

might be a stupid question...
I am a new to ruby and recently I am writing a rake task to merge multiple tables into a general one. One thing I need to do is to fetch the date from the database and then convert the date into two integers as year and month and then save them into two separate columns.
I finished this task file last week but unfortunately that file is removed by accident, so I have to write the code again. I didn't remember how I manipulated the date in the original file, I think that the way I took in the original file is way more straightforward than the current code. The current code is as follows.
fetched_time=DateTime.strptime(pr.fetched_time,"%Y-%m-%d")
dr.year = fetched_time.strftime('%Y').to_i
dr.month = fetched_time.strftime('%m').to_i
I have tried many key words to search, but none of the results is helpful. Is the following code the best way to convert the date string to integer?
Thank you very much.
Yes possible, by using Date#year:
require 'date'
d = Date.parse("20-08-2013")
d.year # => 2013
now = Time.now.to_s
# => "2013-09-10 11:09:14 -0500"
fetched_time=DateTime.strptime(now, "%Y-%m-%d").to_s
# => "2013-09-10T00:00:00+00:00"
year = Date.parse(fetched_time).year
# => 2013
month = Date.parse(fetched_time).month
# => 9
year.class
# => Fixnum
month.class
# => Fixnum
Or
fetched_date=Date.strptime(now, "%Y-%m-%d").to_s
# => "2013-09-10"
date = Date.parse(fetched_date)
# => #<Date: 2013-09-10 ((2456546j,0s,0n),+0s,2299161j)>
Wouldn't you rather use a Date object than a String anyway? What do timestamps consist of? I'm new to Rails and ActiveRecord.
What are you setting your ActiveRecord::Base.default_timezone = # to be?
In case you want to know what those extra numbers are in a Date object
try pluging them in to
Date.jd(2299161)
# => #<Date: 1582-10-15 ((2299161j,0s,0n),+0s,2299161j)>
Date.jd(2456546)
# => #<Date: 2013-09-10 ((2456546j,0s,0n),+0s,2299161j)>
They are Julian Day Numbers. That last one is for calendar reform for Italy and some catholic countries.
Date::ITALY
# => 2299161

How do I find and extract a date from string values

I have a string ruby something like this.
mystring = "some string value with a date 02/02/2002"
and I would like to extract just the date in order to store it in a database. I am pretty sure I'm going to need some sort of regex and way of searching for the pattern and grabbing it from the string.
Not real sure what needs to be done here.
I found this Regex online that is supposed to allow you to match that date formate.
reg = Regexp.new("^\d{1,2}\/\d{1,2}\/\d{4}$")
How would I go about using that to parse out the above date from the string ?
Kinda cool:
1.9.2-p290 :005 > "some string value with a date 02/02/2002".to_date
=> Sat, 02 Feb 2002
1.9.2-p290 :013 > "some another string 05/07/2012 with stuff after".to_date
=> Thu, 05 Jul 2012
And then do with it anything you want since its class is Date.
(I know it's not regex, but I still think it's cool ;P)
How about this?
s = "some string value with a date 02/02/2002"
regex = /\d{1,2}\/\d{1,2}\/\d{4}/
s[regex] # => "02/02/2002"
Note that you don't need the ^ and $ in your regex as you won't be matching the string in its entirety.
You can try https://rubygems.org/gems/dates_from_string:
text = "1988-1990 and 2000 and one more date 28.04.2015"
dates_from_string = DatesFromString.new()
dates_from_string.get_structure(text)
#=> returns
# [{:type=>:year, :value=>"1988", :distance=>0, :key_words=>[]},
# {:type=>:year, :value=>"1990", :distance=>2, :key_words=>[]},
# {:type=>:year, :value=>"2000", :distance=>5, :key_words=>[]},
# {:type=>:year, :value=>"2015", :distance=>0, :key_words=>[]},
# {:type=>:month, :value=>"04", :distance=>0, :key_words=>[]},
# {:type=>:day, :value=>"28", :distance=>0, :key_words=>[]}]

Parsing a custom DATE_FORMAT with DateTime in Rails

How do I get DateTime to parse a custom date format(i.e. 'x-%Y')?
I've set the format within an initializer with (as per the RoR API):
Time::DATE_FORMATS[:x_year] = 'x-%Y'
Date::DATE_FORMATS[:x_year] = 'x-%Y'
and when I call:
DateTime.strptime('x-2011', 'x-%Y')
The correct result is returned, but
DateTime.parse('x-2011')
Throws an
ArgumentError: invalid date
never heard of such a possibility. However, you could still do something like:
class DateTime
class << self
alias orig_parse parse
end
def self.parse(string, format = nil)
return DateTime.orig_parse(string) unless format
DateTime.strptime(string, Date::DATE_FORMATS[format])
end
end
in your example it might look like that:
Date::DATE_FORMATS.merge!({:xform => "x-%Y"})
DateTime.parse('x-2011', :xform) #=> Sat, 01 Jan 2011 00:00:00 +0000
You could get rid of 'format' attribute and iterate && validate/rescue through DATE_FORMATS instead

Resources