How to convert epoch time to Human readable in Teradata - 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!!

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');

Convert epoch with milliseconds into Date format in PL/SQL

I have a column in my table (Data_type Number(16,0)) which stores the epoch time with milliseconds.
Eg :- 1491456096759
I want to write a select statement to format this into readable format which includes milliseconds 'YYYY-MM-DD HH24:MI:SS.FF'.
Is there any direct functions that i can use for this conversion??
I have already tried this option
select to_date('19700101', 'YYYYMMDD') + ( 1 / 24 / 60 / 60 / 1000) * 1491456096759
from dual;
But not able to print that date in 'YYYY-MM-DD HH24:MI:SS.FF' format
Please try this:
SELECT TO_TIMESTAMP('1970-01-01 00:00:00.0'
,'YYYY-MM-DD HH24:MI:SS.FF'
) + NUMTODSINTERVAL(1493963084212/1000, 'SECOND')
FROM dual;
Or this if you want to return a string:
SELECT TO_CHAR(
TO_TIMESTAMP('1970-01-01 00:00:00.0'
,'YYYY-MM-DD HH24:MI:SS.FF'
) + NUMTODSINTERVAL(1493963084212/1000, 'SECOND')
,'YYYY-MM-DD HH24:MI:SS.FF')
FROM dual;

Teradata DATEDIFF Error

Hi i am getting an error as expected something like END keyword between DATEDIFF and (
for the below statement under
select
case when CC.CASE_STS_CD in ( 'Closed', 'Auto Closed') then
DATEDIFF(second,CC.REC_DTTM_PST,CC.CRT_DTTM_PST) end as CASE_RES_DUR_IN_SECS,
Assuming that your fields are DATE datatype (otherwise you'll need to cast):
SELECT
CASE WHEN
CC.CASE_STS_CD IN ('Closed','Auto Closed') THEN
(CC.REC_DTTM_PST - CC.CRT_DTTM_PST) * 86400
END AS CASE_RES_DUR_IN_SECS
There's no DATEDIFF function in Teradata.
This is a generic SQL UDF I wrote a few years ago for calculating the difference of two timestamps in seconds:
REPLACE FUNCTION TimeStamp_Diff_Seconds
(
ts1 TIMESTAMP(6)
,ts2 TIMESTAMP(6)
)
RETURNS DECIMAL(18,6)
LANGUAGE SQL
CONTAINS SQL
RETURNS NULL ON NULL INPUT
DETERMINISTIC
SQL SECURITY DEFINER
COLLATION INVOKER
INLINE TYPE 1
RETURN
(CAST((CAST(ts2 AS DATE)- CAST(ts1 AS DATE)) AS DECIMAL(18,6)) * 60*60*24)
+ ((EXTRACT( HOUR FROM ts2) - EXTRACT( HOUR FROM ts1)) * 60*60)
+ ((EXTRACT(MINUTE FROM ts2) - EXTRACT(MINUTE FROM ts1)) * 60)
+ (EXTRACT(SECOND FROM ts2) - EXTRACT(SECOND FROM ts1))
;

PL/SQL Adding hours to timestamp parameter

I got parameter
:dateFrom
which gonna be used as an argument in a function as a TIMESTAMP. I need to add to :dateFrom + 7 hours, how can I do that?
If your parameter is not already a timestamp, use to_timestamp or to_date to convert it:
to_timestamp(dateFrom,'mm/dd/yyyy hh24:mi:ss')
(substitute the appropriate mask based on the format of your input parameter)
Then just add 7/24.
to_timestamp(dateFrom,'mm/dd/yyyy hh24:mi:ss') + 7/24;
Adding 1 adds a full day, so adding 1/24 adds 1 hour.
This can also be done with the INTERVAL operator:
to_timestamp(dateFrom,'mm/dd/yyyy hh24:mi:ss') + INTERVAL '7' hour
Here is some PL/SQL that will:
DECLARE
dateFrom TIMESTAMP;
BEGIN
dateFrom := SYSTIMESTAMP;
DBMS_OUTPUT.PUT_LINE('BEFORE :: ' || dateFrom);
dateFrom := dateFrom + INTERVAL '2' HOUR;
DBMS_OUTPUT.PUT_LINE('AFTER :: ' || dateFrom);
END;
/
Look into the INTERVAL operator.
You can do like this,
select dateFrom + interval '7' hours from dual
In the arithmetic of the dates, in Oracle, when you add a number, it is intended as NUMBER OF DAYS.
7 hours are 7/24 days, so you have simply to add 7/24.

sqlite - making TIMEDIFF as in MySQL

I want to make a function call that hase efect in SQLite like TIMEDIFF in MySQL.
I made this:
select strftime('%s','2012-01-01 12:00:00') - strftime('%s','2004-01-01 02:34:56')
but this is just the number of seconds. So how can i make a str like %Y-%m-%d %H:%M:%S where %H:%M:%S is the hours, minutes and seconds difference, and when it is bigger then 24 hours then %d will show how much dais it is and so on with %Y and %m.
You cannot represent a time difference with %Y-%m-%d ..., at least not as a date format. How would you express less than a day of difference? (0000-00-00 ... is not a valid date). Also, what would a month be? 30 days? 31 days? 23423432 days?
I suggest you keep your difference in seconds, and when presenting it you adapt it as necessary.
On the other hand, if you really want to do as you asked, here's one way:
sqlite> select datetime(strftime('%s','2012-01-01 12:00:00')
- strftime('%s','2004-01-01 02:34:56') - 62167305600, 'unixepoch');
0007-12-31 09:25:04
Even if I feel the downvote by the OP wasn't justified, I can't stop myself from explaining why what I mentioned above as clearly not a very good option returns "incorrect" results when the time difference is less than 1 day: the reason is implied in what I wrote above: there is no such date as 0000-00-00 ... so instead the datetime returned goes in negative territory: -001-12-31 ...
Here's a way to obtain 438:53:45, but it's quite involved:
earlier date: d1
later date: d2
select
cast(
(strftime('%s', d2) - strftime('%s', d1)) / 86400 * 24
+ cast(strftime("%H", time(strftime('%s', d2)
- strftime('%s', d1), 'unixepoch'))
as int)
as text)
|| ":"
|| substr(time(strftime('%s', d2) - strftime('%s', d1), 'unixepoch'), 4);
Example:
d1 = '2004-01-01 02:34:56'
d2 = '2012-01-01 12:00:00'
sqlite> select cast((strftime('%s','2012-01-01 12:00:00') - strftime('%s','2004-01-01 02:34:56')) / 86400 *24 + cast(strftime("%H", time(strftime('%s','2012-01-01 12:00:00') - strftime('%s','2004-01-01 02:34:56'), 'unixepoch')) as int) as text)
|| ":"
|| substr(time(strftime('%s','2012-01-01 12:00:00') - strftime('%s','2004-01-01 02:34:56'), 'unixepoch'), 4);
70137:25:04

Resources