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=>[]}]
Related
Why do I get different outcomes in these two queries?
Query 1 = false (creating array of shift IDs then checking if shift ID is in array):
shifts = Shift.where('date_time BETWEEN ? AND ?', Time.zone.now - 3.hours, Time.zone.now + 24.hours).pluck(:id)
shifts.include?(16923) # false
Query 2 = true (checking if shift date_time is between a time range):
Shift.find(16923).date_time.between?(Time.zone.now - 3.hours, Time.zone.now + 24.hours) # true
The attribute date_time is a string, can that have anything to do with it?
At the time of writing, here are the current results:
Shift.find(16923).date_time = "2018-09-01T07:45:00+00:00"
Time.zone.now - 3.hours = Fri, 31 Aug 2018 13:34:07 BST +01:00
Time.zone.now + 24.hours = Sat, 01 Sep 2018 16:35:22 BST +01:00
Looks to me that it's between those two ranges, so why is it not included in the first array?
date_time is a String or a DateTime object? that may be the problem.
Because both String and Datetime objects accept a between? method, both inherited at the end from Comparable https://apidock.com/ruby/Comparable/between%3F
A String will be compared alfabethically
'11'.between?('0','2') # => true
A DateTime object will call between? on a Time objects which is represented as an integer and it's compared ordinally
11.between?(0,2) # => false
If date_time is a String, I'd suggest to change it to a DATETIME column type, it makes more sense semantically. If you can't change it, you can add a custom getter to return a DateTime object parsing the string.
def date_time
DateTime.parse(self[:date_time])
end
I'm not that familliar with SQL operators and it's optimizations, but I'm guessing it is comparring both ordinally, that's would explain why the query works and not the between? method. Still I can't confirm this, I'm just guessing (maybe it even depends on the implementation and the table engine, I don't know).
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
Can someone explain what's happening here? This is a much simplified example of some weirdness trying to set a hash key in my rails 3.0.11, mongomapper 0.9.0 app.
class Foo
key :a, Hash
key :b, Hash
end
> foo = Foo.new( :a=>{:timezone=>"Adelaide"}, :b=>{:timezone=>"Azores"} )
> foo.a[:time] = Time.use_zone(foo.a[:timezone]){Time.zone.now}
=> Fri, 11 May 2012 20:20:36 AZOST +00:00
> foo.a[:time]
=> nil
It didn't actually set the hash key to the return value when the timezone from the same hash was used. BUT:
> foo.a[:time] = Time.use_zone(foo.b[:timezone]){Time.zone.now}
=> Sat, 12 May 2012 05:51:07 CST +09:30
> foo.a[:time]
=> Sat, 12 May 2012 05:51:07 CST +09:30
Use the b hash timezone and it stores the value. What? I can store the return value of the use_zone block in a local variable and then set the hash key, or use a static string for Timezone etc, but I can't set the key when the block uses the timezone value from the hash itself?
Try this instead:
foo = Foo.new( :a=>{:timezone=>"Adelaide"}, :b=>{:timezone=>"Azores"} )
Time.use_zone(foo.a[:timezone]){
foo.a[:time] = Time.zone.now
}
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
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