How to convert epoch to datetime redshift? - datetime

I work in dbeaver. I have a table x.
TABLE x has a column "timestamp"
1464800406459
1464800400452
1464800414056
1464800422854
1464800411797
The result I want:
Wed, 01 Jun 2016 17:00:06.459 GMT
Wed, 01 Jun 2016 17:00:00.452 GMT
Wed, 01 Jun 2016 17:00:14.056 GMT
Wed, 01 Jun 2016 17:00:22.854 GMT
Wed, 01 Jun 2016 17:00:11.797 GMT
I tried redshift query
SELECT FROM_UNIXTIME(x.timestamp) as x_date_time
FROM x
but didn't work.
Error occurred:
Invalid operation: function from_unixtime(character varying) does not exist
I also tried
SELECT DATE_FORMAT(x.timestamp, '%d/%m/%Y') as x_date
FROM x
Error occurred:
Invalid operation: function date_format(character varying, "unknown") does not exist
Is there any wrong with the syntax? Or is there another way to convert to human readable date and time?

Redshift doesn't have the from_unixtime() function. You'll need to use the below SQL query to get the timestamp. It just adds the number of seconds to epoch and return as timestamp.
select timestamp 'epoch' + your_timestamp_column * interval '1 second' AS your_column_alias
from your_table

UDF is going to be pretty slow. Checked execution time for 3 solutions and 1k rows.
The slowest -
-- using UDF from one of the answers
SELECT from_unixtime(column_with_time_in_ms/ 1000)
FROM table_name LIMIT 1000;
Execution time: 00:00:02.348062s
2nd best -
SELECT date_add('ms',column_with_time_in_ms,'1970-01-01')
FROM table_name LIMIT 1000;
Execution time: 00:00:01.112831s
And the fastest -
SELECT TIMESTAMP 'epoch' + column_with_time_in_ms/1000 *INTERVAL '1 second'
FROM table_name LIMIT 1000;
Execution time: 00:00:00.095102s
Execution time calculated from stl_query -
SELECT *
,endtime - starttime
FROM stl_query
WHERE querytxt ilike('%table_name%limit%')
ORDER BY starttime DESC;

The simplest solution is to create from_unixtime() function:
CREATE OR REPLACE FUNCTION from_unixtime(epoch BIGINT)
RETURNS TIMESTAMP AS
'import datetime
return datetime.datetime.fromtimestamp(epoch)
'
LANGUAGE plpythonu IMMUTABLE;
See Redshift documentation on UDF for details

For quick reference, here is the SQL UDF implementation of the from_unixtime function shown above in Python. I've not tested the performance but I imagine it would be similar to the plain SQL version. It's a whole lot easier to write though.
Note: this calculates the number of seconds from the epoch.
CREATE FUNCTION from_unixtime (BIGINT)
  RETURNS TIMESTAMP WITHOUT TIME ZONE
IMMUTABLE
as $$
  SELECT TIMESTAMP 'epoch' + $1 / 1000 * interval '1 second'
$$ LANGUAGE sql;

I used it like this
CAST(DATEADD(S, CONVERT(int,LEFT(column_name, 10)), '1970-01-01')as timestamp) as column_name
SELECT
,task_id
,CAST(DATEADD(S, CONVERT(int,LEFT(SLA, 10)), '1970-01-01')as timestamp) as SLA
FROM my_schema.my_task_table ;

Related

Select data based on month and year

We storing date as String in column created_at by below format 2019-10-09T15:29:28.000+08:00 in Moor.
We would like to write a select query, to retrieve data where month are October and year is 2019.
Future<ABC> selectReadingBasedOnMonth(
int month, int year) {
return (select(abcs)
..where((t) {
final sqliteDate = FunctionCallExpression<DateTime, DateTimeType>(
'date', [t.createdAt]);
return sqliteDate.year.equals(year) &
sqliteDate.month.equals(month);
}))
.getSingle();
}
But we are not getting any data. This is the query displayed in log
I/flutter (12004): Moor: Sent SELECT * FROM abcs WHERE
(CAST(strftime("%Y", date(created_at), "unixepoch") AS INTEGER)) = ?
AND (CAST(strftime("%m", date(created_at), "unixepoch") AS INTEGER)) =
?; with args [2019, 10]
The unixepoch modifier can only be used with date/time strings that are solely digits.
The "unixepoch" modifier (11) only works if it immediately follows a
timestring in the DDDDDDDDDD format.
This modifier causes the
DDDDDDDDDD to be interpreted not as a Julian day number as it normally
would be, but as Unix Time - the number of seconds since 1970.
If the
"unixepoch" modifier does not follow a timestring of the form
DDDDDDDDDD which expresses the number of seconds since 1970 or if
other modifiers separate the "unixepoch" modifier from prior
DDDDDDDDDD then the behavior is undefined.
For SQLite versions before
3.16.0 (2017-01-02), the "unixepoch" modifier only works for dates between 0000-01-01 00:00:00 and 5352-11-01 10:52:47 (unix times of
-62167219200 through 106751991167).
Date And Time Functions
For example consider the following (based upon your query) :-
DROP TABLE IF EXISTS abcs;
CREATE TABLE IF NOT EXISTS abcs (created_at TEXT);
INSERT INTO abcs VALUES ('2019-10-09T15:29:28.000+08:00');
SELECT *,
CAST(strftime('%Y', date(created_at)/*, 'unixepoch'*/) AS INTEGER) AS year_nounixepoch,
CAST(strftime('%m', date(created_at)/*, 'unixepoch'*/) AS INTEGER) AS month_nounixepoch,
CAST(strftime('%Y', date(created_at), 'unixepoch') AS INTEGER) AS year_invalid,
CAST(strftime('%m', date(created_at), 'unixepoch') AS INTEGER) AS month_invalid,
CAST(strftime('%Y', strftime('%s',date(created_at)), 'unixepoch') AS INTEGER) AS year_unixepoch,
CAST(strftime('%m', strftime('%s',date(created_at)), 'unixepoch') AS INTEGER) AS month_unixepoch
FROM abcs
WHERE CAST(strftime('%Y', strftime('%s',date(created_at)), 'unixepoch') AS INTEGER) = 2019 AND CAST(strftime('%m', strftime('%s',date(created_at)), 'unixepoch') AS INTEGER) = 10;
DROP TABLE IF EXISTS abcs; /* cleanup test environment */
Note that single quotes have been used to replace double quotes, which would be the correct SQL although this discrepancy may be due to how the message is output.
This results in :-
i.e. where the unixepoch modifier has been used it results in null as the date/time is not solely digits.
the selection criteria, with unixepoch via strftime('%s',..... works as expected.
Thanks for the answer provided by simolus3
final asDate = FunctionCallExpression('date', [t.createdAt]);
final year = FunctionCallExpression<String, StringType>(
'strftime', [const Constant<String, StringType>('%Y'), asDate]);
final month = FunctionCallExpression<String, StringType>(
'strftime', [const Constant<String, StringType>('%m'), asDate]);
return year.equals('2019') & month.equals('07');

How to convert the JSON date with to_date function

How to convert the specific string Aug 6, 2018 3:17:11 PM with the function to_date?
That string is a result of a Java parsing mechanism for JSON. I would like to be able to recover it directly from oracle.
My real problem is much more comprehensive that looks to be. It evolves the APEX_JSON usage, but it is not the question. Here something near of real scenario.
Use the Mon DD, YYYY HH12:MI:SS AM format model:
SQL Fiddle
Query 1:
SELECT TO_DATE(
'Aug 6, 2018 3:17:11 PM',
'Mon DD, YYYY HH12:MI:SS AM'
) As dt
FROM DUAL
Results:
| DT |
|----------------------|
| 2018-08-06T15:17:11Z |

Coversion of IST date format to Oracle sysdate format

How can I to convert from Indian standard time format to oracle date format.
Eg:
Mon May 23 2016 00:00:00 GMT+0530 (India Standard Time)
required format
23-May-16
This parses the input string and returns a date value to you:
select cast(to_timestamp_tz('Mon May 23 2016 00:00:00 GMT+0530', 'Dy Mon DD YYYY HH24:MI:SS "GMT"TZHTZM') as date) as converted_to_date_value
from dual;
This parses the input string to a "timestamp with time zone" value and formats the value back to a string in your desired format:
select to_char(to_timestamp_tz('Mon May 23 2016 00:00:00 GMT+0530', 'Dy Mon DD YYYY HH24:MI:SS "GMT"TZHTZM'), 'DD-Mon-RR') as converted_to_your_format
from dual;
Enjoy!
Footnote: Please note that there's no such thing as "oracle date format" which you refer to. Oracle has its date data type, which can have many many many different display intepretations depending on your client as well as server locale settings.

How to convert epoch time to Human readable in Teradata

In my Teradata table, I have the epoch timestamps under the column dhTimestamp
dhTimestamp
1435308067705
1434965874565
1434763800794
1434775876034
1434765207057
How can I convert the epoch timestamp to Human Date/Time format on Teradata?
This is a SQL UDF for standard unixtime:
/**********
Converting Unix/POSIX time to a Timestamp
Unix time: Number of seconds since 1970-01-01 00:00:00 UTC not counting leap seconds (currently 24 in 2011)
Also working for negative numbers.
The maximum range of Timestamps is based on the range of INTEGERs:
1901-12-13 20:45:52 (-2147483648) to 2038-01-19 03:14:07 (2147483647)
Can be changed to use BIGINT instead of INTEGER
20101211 initial version - Dieter Noeth
**********/
REPLACE FUNCTION Epoch2Timestamp (UnixTime INT)
RETURNS TimeStamp(0)
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
RETURNS NULL ON NULL INPUT
SQL SECURITY DEFINER
COLLATION INVOKER
INLINE TYPE 1
RETURN
CAST(DATE '1970-01-01' + (UnixTime / 86400) AS TIMESTAMP(0))
+ ((UnixTime MOD 86400) * INTERVAL '00:00:01' HOUR TO SECOND)
;
SELECT
Epoch2Timestamp(-2147483648)
,Epoch2Timestamp(0)
,Epoch2Timestamp(2147483647)
;
But your values seem to include milliseconds, this needs a modified calculation:
CAST(DATE '1970-01-01' + (UnixTime / 86400000) AS TIMESTAMP(3))
+ ((UnixTime / 1000.000 MOD 86400) * INTERVAL '00:00:01' HOUR TO SECOND)
Edit 2016-07-01:
There was an issue with dayight saving time (see this thread on Teradata's on DevEx), this should fix it:
-- Unix time to Timestamp WITH TIME ZONE (+00:00)
REPLACE FUNCTION UnixTime_to_TimeStamp_TZ (UnixTime INT)
RETURNS TIMESTAMP(0) WITH TIME ZONE
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
SQL SECURITY DEFINER
COLLATION INVOKER
INLINE TYPE 1
RETURN
((CAST(DATE '1970-01-01' + (UnixTime / 86400) AS TIMESTAMP(0) AT 0)) AT 0)
+ ((UnixTime MOD 86400) * INTERVAL '00:00:01' HOUR TO SECOND);
-- Unixtime to Timestamp, implicit TIME ZONE of the local session
REPLACE FUNCTION UnixTime_to_TimeStamp (UnixTime INT)
RETURNS TIMESTAMP(0)
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
SQL SECURITY DEFINER
COLLATION INVOKER
INLINE TYPE 1
RETURN
CAST(((CAST(DATE '1970-01-01' + (UnixTime / 86400) AS TIMESTAMP(0) AT 0)) AT 0)
+ ((UnixTime MOD 86400) * INTERVAL '00:00:01' HOUR TO SECOND) AS TIMESTAMP(0));
This is the most simplied way to convert EPOCH TO TERADATA LOCAL.
SELECT
dhTimestamp as unix_epoc_time ,
to_timestamp(unix_epoc_time) utc,
cast(cast(utc as char(19))||'+00:00' as timestamp(0) with time zone) AT LOCAL
If you have epoch with more than 10 digit , then chop the numbers after 10th digit, It will just work fine.
remember , Unix time is in UTC.
your system will treat this utc as local. So, let us make it understand that it is UTC by adding '+00:00' and then convert it to your LOCAL using AT LOCAL OR using either of these "America Central" , "America Eastern" , "America Mountain" etc..
I was able to convert epoch column to timestamp using below query..
SELECT CAST((date '1970-01-01' + CAST(epochtimecolumn/1000 AS INTEGER)/86400) AS TIMESTAMP(6)) + (CAST(epochtimecolumn/1000 AS INTEGER) MOD 86400) * INTERVAL '00:00:01' HOUR TO SECOND + (epcho_time_column_with_milliseconds MOD 1000) * INTERVAL '00:00:00.001' HOUR TO SECOND from table_name
Just replace epochtimecolumn with your column in the above query to run it in teradata.
Hope it helps!!

How to convert 2001 based timestamp to datetime in SQLite?

ZPUBLICATIONDATETIME is of type TIMESTAMP.
So when I do this:
SELECT strftime('%d - %m - %Y ', datetime(ZPUBLICATIONDATETIME, 'unixepoch')) FROM ZTNNEWS;
I get 26 - 05 - 1984 instead of 2015. iOS (Core Data) writes datetime on 1 Jan 2001 based. What is the best approach to get the right date conversion?
Shall I just add 31 years to it or is there an alternative to unixepoch to put in there?
Essentially what I am trying to do is to get the records from past two days:
select *
from ZTNNEWS
where DATETIME(ZPUBLICATIONDATETIME) > DATETIME('now', '-2 day')
But because ZPUBLICATIONDATETIME is of type TIMESTAMP rather than Datetime, it doesn't output anything.
Any advice please?
Just had the same problem. Adding the date value to the seconds of 1 Jan 2001 seems to do the job:
SELECT * FROM ztnnews WHERE DATETIME(zpublicationtime + 978307200) > DATETIME('now', '-2 day');
I used ruby to get the seconds of 1 Jan 2001:
$ irb
2.2.3 :001 > require "time"
=> true
2.2.3 :002 > Time.parse( "2001-01-01T00:00:00Z").to_i
=> 978307200

Resources