Creating an array of something by not today's date? - ruby

I have two arrays I'm trying to make. The first one is all the "quotes" with a "follow_up_date" that is today's date. My code looks like:
#dailyTasks = Quote.where(:follow_up => 1,:follow_up_date => Date.today())
This works perfectly for me and is not the issue.
My next array is the same concept but all the quotes to be added are quotes with a follow_up_date that is not today's date. Something like this is what I'm looking for:
#upcomingTasks = Quote.where(:follow_up => 1, :follow_up_date => NOT Date.today())
Does anyone know the proper syntax I should be using to add quotes whose date is NOT today's date?

You can use where.not to get that negation:
#upcomingTasks = Quote.where(follow_up: 1).where.not(follow_up_date: Date.today())

You can simply use equality operators
today = Date.today
today == some_other_date
Can also use < and > to check if date is earlier or later than another.
today < some_other_date
If using Date.today, it does not compare the exact time like it would if using Time.now from other time/date related built-ins.

Related

Changing the format from a mySQL datetime format to a different type in ruby?

I am attempting to change an SQL datetime variable (2016-06-09 14:29:34) into a format that looks like this (00:00_20160601). I have tried to follow a couple of SO questions that will allow me to format a Time object.
This is what I have done so far:
start_datetime = "2016-06-09 14:29:34"
t =Time.new(start_datetime)
t.strftime("%H:%M_%Y%d%m")
This results in the time being formatted to 2016-01-01 00:00:00 +0000, which is obviously not what I want. I was wondering if someone could help me format the datetime object the way I specified?
You can do this with DateTime:
require 'datetime'
DateTime.parse("2016-06-09 14:29:34").strftime("%H:%M_%Y%d%m")
#=> "14:29_20160906"
The format you're feeding in is basically ISO-8601 so it's parsed by default.
Feeding that value into Time.new is completely incorrect. The first argument there is the year, the rest have to be supplied separately. That's why you get 2016-01-01, since everything else comes out as defaults.
Time.new is converting automatically and the result of "2016-06-09 14:29:34".to_i is 2016.
It's not entirely clear why your day value changes from 09 in the input to 01 in the desired output, so I'll use the normal thing and output the same as was input:
require 'time'
start_datetime = "2016-06-09 14:29:34"
t = Time.strptime(start_datetime, '%Y-%m-%d %H:%M:%S')
t.strftime('00:00_%Y%m%d') # => "00:00_20160609"
Since the hours and minutes are being thrown away there are a couple of other ways to go about this.
Ignore the hours and minutes when parsing:
t = Time.strptime(start_datetime, '%Y-%m-%d')
Or use a Date object instead of a Time object:
require 'date'
start_datetime = "2016-06-09 14:29:34"
t = Date.strptime(start_datetime, '%Y-%m-%d')
t.strftime('00:00_%Y%m%d') # => "00:00_20160609"

Ruby: How to extract an hour (or day) from a date-time string

I'm pulling date-time strings from a large CSV file, which look like this:
"11/19/2008 21:56"
I'd like to extract the hour only, so I can build a histogram of all the hours to find the most frequent ones. Similarly, I'd like to extract days of the week (names) from the dates and build a histogram of most frequent days.
I'm new to Ruby, looked up the information, for starters tried various forms of the following, but no luck:
require 'date'
puts DateTime.strptime("11/19/2008 21:56", '%I')
Can you please advise a simple (and clear) way to accomplish the above? Also, any suggestions how to represent the results would be great. I'm thinking one hash array for the hours (24 entries) and one for the days (7 entries)? What would be the neatest algorithm to load them up as I iterate through the date-time strings, and then maybe re-sorting them with most frequent on top? Thanks!!
This is the starting point:
dt = "11/19/2008 21:56"
require 'date'
DateTime.strptime(dt, '%m/%d/%Y %H:%M') # => #<DateTime: 2008-11-19T21:56:00+00:00 ((2454790j,78960s,0n),+0s,2299161j)>
Date formats like "11/19/2008" present a problem when parsing because the default is to use this format:
'%d/%m/%Y'
Date blows up when it sees a month value of 19. '%m/%d/%Y' is not as popular around the world as '%d/%m/%Y', which is why Ruby defaults to it.
Once you have the timestamp parsed, you can easily extract parts from it:
datetime = DateTime.strptime(dt, '%m/%d/%Y %H:%M')
datetime.hour # => 21
datetime.wday # => 3
Notice that wday returns values from 0..6, not 1..7, where 0 = Sunday:
%w[Sunday Monday Tuesday Wednesday Thursday Friday Saturday][datetime.wday]
# => "Wednesday"
Rails' ActiveSupport has a lot of useful methods as part of its Date, DateTime and Time support. Using them is easy, and it's easy to cherry-pick which you want if you decide to add them to plain-ol' Ruby code.
"11/19/2008 21:56".split[1]
=> "21:56"
If can be in other formats, but always the only part with a ":" and two digits on each side, you can use
"11/19/2008 21:56"[/\d{2}:\d{2}/]
=> "21:56"
And for day, something similar
"11/19/2008 21:56"[/\d{2}\/\d{2}\/\d{4}/]
=> "11/19/2008"

Slice the last 4 or otherwise handle this input/output pattern, in Ruby?

print('What is the day and hour (ex., Monday 08AM): ')
appoint = gets.slice[0..-4]
puts(appoint)
is returning this error:
/scope.rb:2:in slice': wrong number of arguments (0 for 1..2) (ArgumentError)
from /scope.rb:2:in'
Also tried slice[appoint.length..-4] and some other things.
From reading other questions, I gathered that this was how such a slice was done. I'm not familiar with the regex pattern. I'd actually like to be able tot return the day of the week, as well, which may mean from -5 back to input or everything up until the space with some kind of regex pattern.
Do you want this ?
appoint = gets.slice(-4,4)
For Monday 08AM it returns:
08AM
You can use slice like this: slice(start, length).
In your case start is -4 and length is 4.
EDIT
Or with only brackets:
appoint = gets[-4..-1]
A string is also an array of characters.
Regex exmaple:
s = "Monday 08AM"
day = /[a-zA-Z]+/
s[day]
=> "Monday"
# \d? to also catch 8AM without 0 at the start
hour = /\d?\d[paPA][mM]/
s[hour]
=> "08AM"
Regex tutorial from Ruby 1.9.3 docs

How to find dates in a csv file using a regular expression and store in an array [using Ruby]?

I have data stored in a csv file that looks like this:
Date,BLOCK,,Wood,Miscellaneous,,Totals,MO
Saturday,4055-RU,4055-AR,4091,1139,1158,,100
11/13/15,C Sort,B,C,iGPS,PECO,,
Starting,758,"3,936",840,0,0,"5,534",
Sorted,656,736,540,162,64,"2,158",
Subtotal 1,"1,414","4,672","1,380",162,64,"7,692",
Shipped,0,"1,152",620,162,64,"1,898",
,"1,414","3,520",860,0,0,"5,794",
Physical,"1,414","3,520",860,0,0,"5,794",
Variance,0,0,0,0,0,0,
Date,BLOCK,,Wood,Miscellaneous,,Totals,MO
Saturday,4055-RU,4055-AR,4091,1139,1158,,100
11/14/15,C Sort,B,C,iGPS,PECO,,
Starting,758,"3,936",840,0,0,"5,534",
Sorted,656,736,540,162,64,"2,158",
Subtotal 1,"1,414","4,672","1,380",162,64,"7,692"
Shipped,0,"1,152",620,162,64,"1,898"
,"1,414","3,520",860,0,0,"5,794"
Physical,"1,414","3,520",860,0,0,"5,794"
Variance,0,0,0,0,0,0
and I need to make an array of all the dates mentioned (in this case, dates = ['11/13/15', '11/14/15'].
I believe it is possible to pull this info out using a regular expression, but I don't really understand how they work/how to go about this. So, how can I extract the dates?
EDIT: I can sort through the data by row using CSV.foreach, but the trouble I am having is to tell the program to pull out anything that matches a date format (ie. 11/13/15). Does that make more sense of my question?
Thank you!
- Sean
The correct one liner is:
File.open('yourfile.csv').read.scan /\d{2}\/\d{2}\/\d{2}/
and by the way \d{2} is so much nicer than \d\d and here's why:
you can see the 2. \d{2} reads like "2 digit number" (once you're
used to it)
if you want to change it to 1 or 2 digits you can do {1,2}
dates = []
File.open('yourfile.csv').each_line do |line|
if m = line.match(/^\d\d\/\d\d\/\d\d/)
dates.push m
end
end
puts dates
BTW. I am sure someone could write this as a one-liner, but this might be a little easier to understand for someone new to Ruby.
I making these assumptions:
All dates are of the format mm/dd/yy.
All dates that you want in the array are at the start of each line.
You don't need to verify that it is a valid date.
You could get a first approximation with this:
dates = CSV.open('x.csv').map{|r| r.select { |x| x =~ /\d\d\/\d\d\/\d\d/ } }.flatten
and then, if needed, scan through the elements of dates to make sure numbers are in the proper ranges (so that you don't accidentally include a date that claims to be Feb 31 2001). If you want to check the format, you could use DateTime.strptime and catch ArgumentErrors:
clean = dates.select do |d|
begin
# I'm guessing on the date format.
DateTime.strptime(d, '%m/%d/%y')
rescue ArgumentError
nil
end
end

Ruby Date.strptime difficulties when parsing 13/Nov/11

When parsing a Jira Custom Field containing a date (e.g. 13/Nov/11) I started with this:
elsif custom.customfieldId == "customfield_10282"
#agenda_item.planned_release_date = custom.values.to_s
But the database stores it as 11/13/0011. So I got clever and used this:
elsif custom.customfieldId == "customfield_10282"
#agenda_item.planned_release_date = Date.strptime(custom.values, "%d/%m/%Y")
And now I get:
private method sub!' called for ["15/Nov/11"]:Jira4R::V2::ArrayOf_xsd_string
C:/Ruby187/lib/ruby/1.8/date/format.rb:429:in_strptime_i'
C:/Ruby187/lib/ruby/1.8/date/format.rb:401:in scan'
C:/Ruby187/lib/ruby/1.8/date/format.rb:401:in_strptime_i'
C:/Ruby187/lib/ruby/1.8/date/format.rb:601:in `_strptime'
[truncated the rest of the stack]
What am I missing?
This works:
p Date.strptime('13/Nov/11', "%d/%b/%y")
Your problems:
`%Y is the year with 4 digits (2011). Use %y
%m is the month in digits (11). Use %b instead (Nov)
If I properly understand your issue, try to use this:
Date.strptime('13/Nov/11', "%d/%b/%y") # => 2011-11-13
You have abbreviated month name and there for you should use b format directive. Beside this because your year contains only two last numbers, use y directive.

Resources