Adding or Subtracting Time From Postgres Timestamps - ruby

I am using the following ruby code, with the PG gem, to return a timestamp that is in Postgres "timestamp without timezone" format. Instead of returning the current value, I would like it to return the value (-1 hour).
def get_latest_timestamp(id)
conn1 = PGconn.open(:dbname => 'testdb')
res = conn1.exec("SELECT MAX(time_of_search) FROM listings WHERE id=#{id}")
res.values[0][0]
end

In Postgres, you can add or subtract an interval to or from a timestamp to produce another timestamp, as described here.
So in this case, assuming time_of_search is a timestamp, you could do
"SELECT MAX(time_of_search) - INTERVAL '1 hour' FROM listings WHERE id=#{id}"

Related

Date query in laravel : start datetime with current

Greeting.
I have One datetime in my table. Its name is start_time. And I have a variable(process_time) that contains the number of seconds to run a process. How to count the number of fields with the following condition:
start_time + process_timen < Present time
You can utilize DB::raw() helper and add the SQL equivelant of what you want to achieve using DATE_ADD and INTERVAL.
$processTime = 15; // seconds
Model::where(DB::raw("DATE_ADD(start_time, INTERVAL $processTime second)"), '<', now())->count();

How can I use a PSQL timestamp function as a parameter in Ruby?

I am using a Ruby method to access task information from a Postgres database.
def query(statement, *params)
#logger.info("#{statement}: #{params}")
#db.exec_params(statement, params)
end
def tasks_completed_for_date(date="CURRENT_DATE")
sql = <<~SQL
SELECT tasks.name AS task_name,
timetable.start_at AS start_at,
timetable.end_at AS end_at,
timetable.duration AS duration,
timetable.start_at::date AS task_date
FROM tasks
JOIN timetable ON tasks.id = timetable.task_id
WHERE timetable.start_at::date = $1
AND timetable.duration IS NOT NULL
ORDER BY tasks.name ASC;
SQL
result = query(sql, date)
if result.ntuples > 0
result.map do |tuple|
{
task_name: tuple['task_name'],
start_at: tuple['start_at'].slice(11, 5),
end_at: tuple['end_at'].slice(11, 5),
total_time: tuple['duration'].slice(0, 5),
task_date: tuple['task_date'].slice(5, 5)
}
end
end
end
I want the default value to of the query to be whatever the current date is. I thought the best way to do this was to set the default parameter in the method called tasks_completed_for_date to the string CURRENT_DATE. This string would be interpreted by PSQL as the method CURRENT_DATE and return data based on that date. Instead I receive the following error:
ERROR: date/time value "current" is no longer supported
I am not using 'current' at all and I know that whatever it is, it's obsolete. Is there a way to pass a PSQL method to the query (in place of $1) as I am trying here that doesn't result in an error?
Your problem is that the $1 placeholder's value will be the string 'CURRENT_DATE', not the literal value CURRENT_DATE. The result is that you're effectively saying 'CURRENT_DATE'::date and that doesn't work:
psql> select 'current_date'::date;
ERROR: date/time value "current" is no longer supported
LINE 1: select 'current_date'::date;
^
You need to either get the literal value current_date into the query or find a string that properly casts to a date. The easiest thing would be to use 'now' since that casts nicely:
psql> select 'now'::date;
date
------------
2019-10-22
(1 row)
A quick change to the method's date argument's default value should be good enough:
def tasks_completed_for_date(date = 'now')
You can replace $1 with one of these methods:
DATE 'today'
DATE 'now'
Also you can use:
TIMESTAMP 'today'
So for example call method as tasks_completed_for_date('today')

Ruby on Rails 3 convert time to DateTime in specific timezone

I have column which stores only time. I want to convert to it into datetime and then to a specific timezone. When I do it on console using only the attribute, it shows correct conversion value. But when I use it in query the query shows the current time in UTC. Suppose I have time "05:15" stored in Central time. Now when I want to fetch records for a interval of 30 minutes plus and minus of this time, I do following,
day = Time.now
# departure_time_from _db below is the name of column in table which store time
departure = departure_time_from _db.change(:day => date.day, :month => date.month, :year => date.year)
departure = departure.in_time_zone("Central Time (US & Canada)")
When I execute above code on console and see the value, it shows correct converted value. But when I use this variable in below query, current time gets used instead of the departure time.
Model.where("column_name > ? and "column_name < ?, departure - 30.minutes, departure + 30.minutes)
The time used in above query should be the time I want i.e Central time zone, but in query output, it shows UTC being used.
Please let me know what i am missing.
It shouldn't matter what time zone the query uses in the where clause as long as it's the same time representation. The time you're seeing in your query output from Rails is most likely the UTC equivalent of the ruby DateTime object being passed to the where statement. So if departure is 12:00 noon (UTC -6) in your Ruby code then the time shown in the SQL query will be 18:00, which corresponds to noon CST.

How can I group on the created_at field and return only the Date and hour

I run the following in Rails:
coe = trackers.where(:trackable_type => "Mailing").count(:group => 'DATE(created_at)')
which returns a hash with the items nicely grouped.
However I want to group not by date only by date but by the hour, but not the minutes or seconds.
How can I run this query so all the heavy lifting is done by Postgresql and not convert after I get the data set back?
My mistake I want to group by Date and Hour. Sorry for the confusion.
It sounds like you want the date_trunc() function:
http://www.postgresql.org/docs/current/interactive/functions-datetime.html#FUNCTIONS-DATETIME-TABLE
I want to group not by date but by the hour, but not the minutes or
seconds.
Bold emphasis mine.
So date_trunc()is probably not what you want, but EXTRACT or date_part():
coe = trackers.where(:trackable_type => "Mailing").count(:group => 'EXTRACT (hour FROM created_at)')

Get the the most recent and the one before the most recent item

I have a table with many anniversaries : Date + Name.
I want to display the next anniversary and the one after with Linq.
How can i build the query ?
I use EF
Thanks
John
Just order by date and then use the .Take(n) functionality
Example with a list of some objects assuming you want to order by Date then Name:
List<Anniversaries> annivDates = GetAnnivDates();
List<Anniversaries> recentAnniv = annivDates.OrderBy(d => d.Date).ThenBy(d => d.Name).Take(2).ToList();
If the anniversaries are stored in regular DateTime structs, they may have the 'wrong' year set (i.e. wedding or birth year). I suggest writing a function which calculates the next date for an anniversary (based on the current day) like:
static DateTime CalcNext(DateTime anniversary) {
DateTime newDate = new DateTime(DateTime.Now.Year, anniversary.Month, anniversary.Day);
if (newDate < DateTime.Now.Date)
newDate = newDate.AddYear(1);
return newDate;
}
Then you proceed with sorting the dates and taking the first two values like described in the other postings:
(from e in anniversaries orderby CalcNext(e.Date) select e).Take(2)

Resources