Rank in-order of relation to the current date. [Rails, Sqlite3] - ruby-on-rails

How do I return information in rank of closeness to the current date irrelevant of the year. If Current date is May 26 2011, the date closeness to May 26 is returned first. My problem was this confusion: I have two dates: Date 1: May 24th 2011 and Date 2: June 1st 2010, ensuring that Date 2 is returned before Date 1. Both because May 24 has passed and also the year factor.
Table:
Name Created_at
Bob 2010-06-01 (YYYY-MM-DD)
Mike 2010-05-07
Fife 2011-05-09
So it would return if current date is May 26 2011:
Bob 2010-06-01 (YYYY-MM-DD)
Mike 2010-05-07
Fife 2011-05-09
What I have so far:
#awesomeDate = Names.order("name").having("date > ?", Date.today)

Related

Calculate correct start date for the below scenarios?

I have below condition.
Order.where('created_at BETWEEN ? AND ?', start_date, end_date)
I want orders between start_date and end_date
But I want to write query for below scenarios.
If today's date is greater than 3rd July 2021 then I want the orders between 1st July 2021 to today's date.
If today's date is less than 3rd July 2021 then I want the orders from last month(1st June 2021) to 3rd July 2021.
How to calculate correct start date?
start_date = (Date.today > Date.new(Date.today.year, Date.today.month,3)) ? Date.today.at_beginning_of_month : Date.today.prev_month.at_beginning_of_month

Efficient Postgresql Query for Sorting Appointments on Simple Calendar with Rails

TL;DR:
I have a database with thousands of appointments that have start_time and end_time attributes. Given a date range (May 26-June 31), how do I find
every appointment that happens throughout this range?
Appointment from May 15 to May 25 NOT included
Appointment from May 15 to May 29 needs to be included
Appointment from June 1 to June 3 needs to be included
Appointment from June 20 to July 5 needs to be included
Appointment from May 15 to July 15 needs to be included (most difficult part of the problem)
Appointment from July 1 to July 4 NOT included
We have an appointment model that has a start_time and an end_time. If an appointment occurs on any days during the monthly view, it needs to be loaded into the instance variable (#monthly_appointments) so that the simple_calendar gem can display it on the calendar.
Example: An appointment from June 1 to June 3 needs to show up when the user views the "June 2020" calendar. An appointment from May 15 to July 15 also needs to show up every single day during June.
There's 6-day padding on each side of the calendar dates, since if the week starts on a Saturday (June 1), you'll have May 26 - May 31 showing on the June calendar (see picture).
You'd think it was just as easy as saying "If an appointment starts or ends during the given month, add that appointment to the instance variable. However, there are cases when an appointment starts on May 15 and goes for 60 days, until July 15. The appointment neither starts nor ends during June, but it needs to still show up on the calendar.
Originally, we told users, "appointments cannot last longer than 6 months" and then we used this lookup where we assumed, "if the appointment started during the last 6 months, include it in the variable and then we'll let the calendar gem work out the rest."
#monthly_appointments = current_user.appointments.includes(:pet).where(start_time: (Time.zone.now).beginning_of_month - 6.months..(Time.zone.now).end_of_month + 6.days))
However, this query can sometimes save 3,000+ appointments in the variable, when, in reality, there are only 50-70 appointments that NEED to be shown for that month.
So, I wrote up the following code, and it succeeds in finding appointments that occur on at least one day during the calendar's timeframe. It compares the monthly calendar's range(May 26..June 31) and an appointment's range(June 1..June 3), and then looks for any dates that occur in both arrays (&). It works well, but it takes a bit of time because it needs to load ALL the appointments for a user (thousands) and then goes through each one to see if it occurs during that month.
Does anyone have any other clever solutions to this query issue? I'm sure something exists out there, but I haven't found it yet. Thanks!
month_dates = ((Time.zone.now.beginning_of_month - 6.days)..(Time.zone.now.end_of_month + 6.days)).to_a
#monthly_appointments = current_user.appointments.includes(:pet).select do |appt|
#create array of appointment dates and see if it intersects any of the monthly date array
appt_dates = (appt.start_time.to_date..appt.end_time.to_date).to_a
(month_dates & appt_dates).present?
end
Models:
Appointment(start_time, end_time, note, user_id, pet_id)
Pet
has_many appointments
User
has_many appointments
Here's an example.
carley = Pet.find(12)
Appointment.create(pet_id: carley.id, start_time: "May 15 2020 06:00:00", end_time: "July 15 2020 06:00:00"...)
When I'm looking at the June 2020 calendar, this appointment needs to show up on every single day.
from_time = '2019-05-26'.to_date
to_time = '2919-06-30'.to_date
#appointments = Appointment.where('start_time <= ? AND end_time >= ?', to_time, from_time)
The above will select all appointments that are included in or overlap the from_time and to_time range, and also appointments that start before the range and end after the range.

Informix today operator

I have a condition qa.actual_date >= today - 1 in a informix query.
Does it fetch the records exactly from the past 24 hours?
Eg:
Curent date and time is 13 Jun 2019 12:45 PM
does qa.actual_date >= today - 1 will fetch the records from 12 Jun 2019 12:45 PM or 12 Jun 2019 12:00 AM
Under Informix, a DATE value refers to a day, and has no explicit time component. Given a current date of 2019-06-13 and assuming the type of qa.actual_date is DATE (and not a DATETIME type), the condition:
qa.actual_date >= TODAY - 1
selects all records where the qa.actual_date value is (any time on) 2019-06-12 or later.
If qa.actual_date is of type DATETIME YEAR TO SECOND or any other type that has an hour, minute, or second component (as well as day, month, year components), then the value of TODAY - 1 will be converted (extended) to that type, and the missing time components will be treated as zeroes.
SELECT EXTEND(TODAY - 1, YEAR TO SECOND) FROM sysmaster:sysdual;
That will return 2019-06-12 00:00:00.

Why does adding and subtracting 2 months to a date not give back the same date?

I'm a bit confused about this outcome, taking today's date minus 2 months, and then taking that date again and adding two months, does not give me today's date when assign the dates to a variable.
Time.zone
"Eastern Time (US & Canada)"
> today = Date.today.in_time_zone
=> Thu, 31 Aug 2017 00:00:00 EDT -04:00
> a = today - 2.months # This is persisted to the db
=> Fri, 30 Jun 2017 00:00:00 EDT -04:00
> b = a + 2.months
=> Wed, 30 Aug 2017 00:00:00 EDT -04:00
If I however, just use the same object, it moves back and forth properly:
> today = Date.today.in_time_zone
=> Thu, 31 Aug 2017 00:00:00 EDT -04:00
> today - 2.months
=> Fri, 30 Jun 2017 00:00:00 EDT -04:00
> today + 2.months
=> Tue, 31 Oct 2017 00:00:00 EDT -04:00
The problem is obviously when "a" gets saved to a database, and then retrieved later on, and calculated plus 2 months..., it should match today's date.
TL;DR
A month is not a fixed duration. Adding or taking a month does not give the same "time shift" depending on which day you are.
The usual algorithm
to add or take months is the following :
try to land on the same day number (4th, 30th, 31st) as you started, just by changing the month
if you would land on an impossible date (like 31th September, 30th February, 29th February for some years) then just go the maximum allowed day number of this month
This implies that adding some months then taking out the same number of months will not necessarily give you back the same date.
Examples :
31st of some month + 1 month --> One would want to get to the 31th of next month
But if there is no 31st of next month (like for 31th of August, no 31st of September), then what to do ?
Usual interpretation would say that you want to go to the end of the month, this is 30th September (for rent or other monthly subscription, for instance)
But usually, 30th of some month - 1 month --> One would want to get to the 30th of the previous month.
That would lead to .... 30th of August. Not 31th of August.
Hence: some date + 1 month - 1 month does not necessarily give the original date !
Another example :
Start at the 30th of August.
Take a month -> 30th of July
Add a month -> You want to get to 30th of August (same number, next month) or to the end of August ?
The default algorithm will try to give the same day number -> 30th of August (which is more logical now)
Also with days...
Note that the same problem happens with days,but much less often ! When some days don't have the same number of hours, for daylight saving days, when adding and taking same number of days you might not get back to the original date and time as you started from.

How do I get a Date from a week number?

I want to find all items created in a given week, and pass in a week number param. (created_at is a normal timestamp.)
Given a week number, what is the easiest way to find a date in that particular week?
(Any date in the week will do, as I will use beginning_of_week and end_of_week in the scope.)
You can get Date objects representing the beginning and end of your week using the commercial method:
week = 41;
wkBegin = Date.commercial(2010, week, 1)
wkEnd = Date.commercial(2010, week, 7)
Now do your find:
Item.find(:all, :conditions->:create_date=>wkBegin..wkEnd.end_of_day)
Assuming you mean "a given week number in the current year", you can do the following:
2.weeks.since(Time.gm(Time.now.year))
=> Fri Jan 15 00:00:00 UTC 2010
Substitute (week_number - 1) for the 1 in the above, and you'll get a date in the desired week.

Resources