How to extract time from CURRENT_TIMESTAMP in Postgresql - sql

Just as we are able to extract the date from timestamps in Postgresql using date(CURRENT_TIMESTAMP), I was wondering if there's a equivalent function to extract time. (formatted as hh:mm:ss)
I want to be able to compare a time value, stored in a column with the time datatype (see https://www.postgresql.org/docs/current/datatype-datetime.html), to the current time just using an SQL query.
Any suggestions are most welcome!

You can either use current_time or casting a timestamp to time: current_timestamp::time
e.g.
where the_time_column >= current_time - interval '6' hour
For details, see Current Date/Time in the Postgres manual

Related

Oracle SQL Select Current Timestamp without Timezone and 24hr Format

I have a Oracle SQL statement where I have to get the current timestamp as one of the columns. But I dont require the Timezone which CURRENT_TIMESTAMP gives or the AM/PM given by LOCALTIMESTAMP.
I require the current timestamp in 24hr format without the timezone.
Is it possible to get that in Oracle SQL?
It seems you're mixing 2 concepts here: "datatype" and "date format mask".
data type: LOCALTIMESTAMP returns datatype TIMESTAMP and CURRENT_TIMESTAMP returns datatype TIMESTAMP WITH TIME ZONE. TIMESTAMP is similar to DATE but has a higher precision. As usual... checking the docs is worth it.
date format mask: determines how you display the date information. Americans can't read 24 hour format, the rest of the world is confused by AM/PM. Fortunately, you can decide how you want to display the date as explained in the oracle docs.
If you just want to return the current date in 24 hour format you could do something like:
SELECT
TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS') as mydate,
<other columns>
FROM
<table_name>
If you need the date to be more precise and you require fractional seconds then you can use SYSTIMESTAMP instead of DATE with a format mask 'DD-MON-YYYY HH24:MI:SS.FF9'

EXTRACT the date and time - (Teradata)

I am trying to extract the date and time from a field in Teradata.
The field in question is:
VwNIMEventFct.EVENT_GMT_TIMESTAMP
Here is what the data look like:
01/02/2012 12:18:59.306000
I'd like the date and time only.
I have tried using EXTRACT(Date, EXTRACT(DAY_HOUR and a few others with no success.
DATE_FORMAT() does not appear to work since I'm on Teradata.
How would I select the date and time from VwNIMEventFct.EVENT_GMT_TIMESTAMP?
If the datatype of EVENT_GMT_TIMESTAMP is a TIMESTAMP, it's simple Standard SQL:
CAST(EVENT_GMT_TIMESTAMP AS DATE)
CAST(EVENT_GMT_TIMESTAMP AS TIME)
If it's a CHAR you need to apply a FORMAT, too:
CAST(CAST(EVENT_GMT_TIMESTAMP AS TIMESTAMP FORMAT 'dd/mm/yyyyBhh:mi:SS.s(6)') AS DATE)
CAST(CAST(EVENT_GMT_TIMESTAMP AS TIMESTAMP FORMAT 'dd/mm/yyyyBhh:mi:SS.s(6)') AS TIME)
Edit:
For simply changing the display format you need to add a FORMAT and a CAST to a string:
CAST(CAST(EVENT_GMT_TIMESTAMP AS FORMAT 'YYYYMMDDHHMI') AS CHAR(12))
or
CAST(CAST(EVENT_GMT_TIMESTAMP AS FORMAT 'YYYYMMDDHHMISS') AS CHAR(14))
If you don't care about display, just want to truncate the seconds:
EVENT_GMT_TIMESTAMP - (EXTRACT(SECOND FROM EVENT_GMT_TIMESTAMP) * INTERVAL '1.000000' SECOND)
Working with timestamps is a bit tricky :-)
I know this is an old topic, but I've struggled with this too. Try:
CAST(EVENT_GMT_TIMESTAMP AS TIMESTAMP(0))
The result will be
01/02/2012 12:18:59
The datatype will still be timestamp, but it will just be the date and time with no microseconds (looks just like a datetime object in Microsoft SQL).

Query on a time range ignoring the date of timestamps

I'm trying to query a purchases table in my rails database (Postgres) and I want to query on time ranges.
For example, I'd like to know how many purchases were made between 2 PM and 3 PM across all dates.
There is a created_at column in this table but I don't see how to accomplish this without searching for a specific date as well.
I've tried:
Purchases.where("created_at BETWEEN ? and ?", Time.now - 1.hour, Time.now)
But this ultimately will just search for today's date with those times.
You need to extract just the hour portion from created_at using PostgreSQL's date_part/extract function.
SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 20
For example, something like this:
Purchases.where(["EXTRACT(HOUR FROM created_at) BETWEEN ? AND ?", 13, 14])
Use a simple cast to time:
Purchases.where("created_at::time >= ?
AND created_at::time < ?", Time.now - 1.hour, Time.now)
This way you can easily test against arbitrary times.
Consider:
Which border to include / exclude. Common practice is to include the lower border and exclude the upper. BETWEEN includes both.
The exact data type (timestamp or timestamp with time zone) and how that interacts with your local time zone:
Ignoring time zones altogether in Rails and PostgreSQL
Index
If you run these queries a lot and need them fast and your table isn't very small, you will want to create a functional index for performance:
CREATE INDEX tbl_created_at_time_idx ON tbl (cast(created_at AS time));
I used the standard SQL syntax cast() instead of the Postgres syntactical shortcut ::. This is required for indices.
This index works for a timestamp [without time zone] since the cast is IMMUTABLE as required for an index. But it does not work for a timestamp with time zone, for the same reasons. You can fix this, but you need to define what you need exactly. Use the AT TIME ZONE construct to define the time zone to extract the time for. For instance, to measure against UTC time:
CREATE INDEX tbl_created_at_time_idx2
ON tbl(cast(created_at AT TIME ZONE 'UTC' AS time));
Similar question dealing with dates ignoring the year:
How do you do date math that ignores the year?

SQLite Current Timestamp with Milliseconds?

I am storing a timestamp field in a SQLite3 column as TIMESTAMP DATETIME DEFAULT CURRENT_TIMESTAMP and I was wondering if there was any way for it to include milliseconds in the timestamp as well?
Instead of CURRENT_TIMESTAMP, use (STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')) so that your column definition become:
TIMESTAMP DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW'))
For example:
CREATE TABLE IF NOT EXISTS event
(when_ts DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')));
To get number of milliseconds since epoch you can use julianday() with some additional calculations:
-- Julian time to Epoch MS
SELECT CAST((julianday('now') - 2440587.5)*86400000 AS INTEGER);
The following method doesn't require any multiplies or divides and should always produce the correct result, as multiple calls to get 'now' in a single query should always return the same result:
SELECT strftime('%s','now') || substr(strftime('%f','now'),4);
The generates the number of seconds and concatenates it to the milliseconds part from the current second+millisecond.
Here's a query that will generate a timestamp as a string with milliseconds:
select strftime("%Y-%m-%d %H:%M:%f", "now");
If you're really bent on using a numeric representation, you could use:
select julianday("now");
The accepted answer only gives you UTC. If you need a local time instead of UTC, use this:
strftime('%Y-%m-%d %H:%M:%f', 'now', 'localtime')

Convert milliseconds to Date/Time

I'm trying to generate a report in PostgreSQL.
It's working -- except one column stored in the database represents a date/time value, but it is stored as an integer representing the number of milliseconds since 1970.
Needless to say, the millisecond value has not much meaning to people reading the report.
Is there a way in SQL to convert milliseconds into some sort of readable date/time value?
I'm not easily able to have the report generated in some other program or language. I'd like the report to be run as a SQL script.
This recipe is from the docs:
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + (millisecond_column/1000) * INTERVAL '1 second'
FROM mytable;
Recent versions of PostgreSQL provide a to_timestamp function to achieve the same.