Db2: How to convert Unix / epoch time to timestamp? - db2

I have a BIGINT value which represents a UNIX timestamp (epoch). How can I convert it to the built-in TIMESTAMP type?
As example, I want to turn 1611140400 into the related date and time. TIMESTAMP_FORMAT does not work.

You can use datetime arithmetics in Db2 and Db2 on Cloud. For Db2 on Cloud (which is running in UTC):
VALUES (TIMESTAMP('1970-01-01') + 1611140400 seconds)
Epoch is seconds since January 1st, 1970 GMT / UTC. Thus, adding your number as seconds to that date will give:
2021-01-20 11:00:00.0
If you are running in a different timezone, you need to take care of it, e.g.:
VALUES (TIMESTAMP(‘1970-01-01-00.00.00.000000’) + 1611140400 seconds + current timezone)

Related

Function to support addition & subtraction of both numbers & date

Need of a generic Postgres function to support addition & subtraction of both number & date (timestamp without time zone).
It's expected to support number + number, date + number, date - number like formats. Type need be identified at runtime if possible. Is it feasible?
PostgreSQL has a number of operators for date arithmetic. To name the most important options for addition:
date + integer → date
date + time without time zone → timestamp without time zone
date + interval → timestamp with time zone
timestamp without time zone + interval → timestamp without time zone
timestamp with time zone + interval → timestamp without time zone
Subtraction works similar.
Multiplication and division exist for interval and double precision.
That works quite the same as in Oracle, so code should not be hard to port.
Some differences:
While Oracle's timestamp with time zone stores the time zone information along with the data, PostgreSQL doesn't. Rather, it converts the timestamp to UTC before storing it, and upon display, it is converted to the timezone setting active in the database connection.
Oracle's date (strangely) has fields for hour to second and is best translated to timestamp(0) without time stamp.
Oracle has two interval data types, but they both can be represented as PostgreSQL's interval.
Oracle does not have an integer data type, so you have to translate Oracle's number to integer for PostgreSQL. This might present a problem if you add numbers with a fraction – that would have to be translated to timestamp + interval.
Replace the Oracle-specific sysdate with clock_timestamp().

time stamp are resetting to Zero when changed from to_date to to_char in postgresql

I need to change the following sql query to the postgres format. how can I do that?
eg:
round((TIME_TO_SEC(testruntest.endtime) - TIME_TO_SEC(testruntest.starttime))/60,2)
I tried this query and got error as "time_to_sec" is not a supported function...
Use the SQL standard EXTRACT function:
EXTRACT(epoch FROM testruntest.endtime)
The documentation describes:
For timestamp with time zone values, the number of seconds since 1970-01-01 00:00:00 UTC (can be negative); for date and timestamp values, the number of seconds since 1970-01-01 00:00:00 local time; for interval values, the total number of seconds in the interval

Tableau Epoch to DateTime with TimeZone

Data has hour field (String datatype). The timestamp is in milliseconds. This is working -
DATEADD('second',INT(INT([Hour])/1000),DATETIME('1970-01-01'))
However, this is NOT WORKING -
DATEADD('hour',-7,(Date("1/1/1970") + (INT(INT([Hour])/(1000*86400))))
The above is returning NULL. -7 is to adjust for my Timezone.
Was able to get it done. May help someone.
Changed the second one to this -
DATEADD('hour',0,(DATETIME("1970-01-01") + INT((INT([Hour])/(86400*1000)))))
As a reference, extract from Tableau own knowledge base:
To convert the field to UTC time, use the following calculation:
DATEADD('second', [Unix time field], #1970-01-01#)
To convert the field in Unix time to a different time zone, use the
following calculation:
DATEADD('minute', INT([Unix time field]/60 + ),
#1970-01-01#)
For example, to convert the field in Unix time to India Standard Time
(IST), use the following calculation:
DATEADD('minute', INT([Unix time field]/60 + 330), #1970-01-01#)

indexing timestamptz for specific timezone

My console is PST.
Database server and times stored are GMT.
I'm having to run queries like so:
SELECT x,y,z
FROM tbl_msg
WHERE (msg_datetime AT TIME ZONE 'BST') BETWEEN '2016-11-21'::date and '2016-11-22'::date;
Indexing 101 says that performing this operation on msg_datetime will now avoid the index and this is what I'm seeing.
So I need advice with an indexing solution for this.
Can I index this timezone? or alter this query so that it queries these times in BST, converted to GMT?
You should have msg_datetime column of type timestamp with time zone (or shorter alias timestamptz) with normal index.
Then, to get data for these 2 days, you should:
set timezone 'Europe/London'; -- once, on connection start
SELECT x,y,z
FROM tbl_msg
WHERE
msg_datetime>='2016-11-21 00:00:00'
and
msg_datetime<'2016-11-23 00:00:00';
You should not use ordinary timestamp, as it stores literal date and hour without information about which timezone it actually meant. A timestamp with time zone type will automatically convert your client's configured time to internal representation (which is in UTC) and back. You can also express timestamptz from non-default timezone using for example '2016-11-23 00:00:00 Asia/Tokyo'.
Also you should not use BST - because you'd need to use GMT on winter and remember when to use which. You should use 'Europe/London' or other "city" timezones (list), which are right both in summer and in winter.

converting db2 datestamp to Unix timestamp

How can i convert 2012-04-12 00:00:00 to a unix timestamp in DB2. is there any inbuild function available in sql s
Thank you.
Using the DAYS and MIDNIGHT_SECONDS is much more precise than TIMESTAMPDIFF:
SELECT
86400*(DAYS(CURRENT TIMESTAMP - CURRENT TIMEZONE)-DAYS('1970-01-01'))
+ MIDNIGHT_SECONDS(CURRENT TIMESTAMP - CURRENT TIMEZONE)
"UNIX_TIMESTAMP"
FROM SYSIBM.SYSDUMMY1
By Unix timestamp I assume you mean the number of seconds (or whatever) since 1970-01-01 00:00:00 UTC.
There is no built in functionality for this in DB2 (as of V6R1).
You're also up against the following issues:
All timestamps in DB2 are 'local time' - they contain no timezone information, and all CURRENT_TIMESTAMP writes are based on what time the requesting system thinks it is, not the host.
Daylight savings time changes frequently. You would need to add overhead to manage this for your conversion.
The TIMESTAMPDIFF function returns an estimate, not an exact value. You could probably survive for the years/months durations, over sufficient differences, but days aren't likely to cut it.
Timestamp arithmetic is imprecise (among other things, months are assumed to be always 30 days in length...)
Your best bet will be to start using DAYS (which returns the number of days since 0001-01-01). Keep in mind you better do everything in UTC, because it will not take DST into account.