add
remove
language
chart
show hidden
hide
db<>fiddle
Db2
DocumentDB
DuckDB
Firebird
MariaDB
MySQL
Oracle
Postgres
SQL Server
SQLite
TimescaleDB
YugabyteDB
11.1
11.5
12.1
0.114 (MongoDB 7.0)
0.116 (MongoDB 7.0)
1.4 LTS
3.0
4.0
5.0
10.2
10.3
10.4
10.5
10.6
10.7
10.8
10.9
10.11
11.4
11.8
12.3
5.5
5.6
5.7
8.0
8.4
9.7
11g Release 2
18c
21c
23c
23ai
26ai
8.4
9.3
9.4
9.5
9.6
10
11
12
13
14
15
16
17
18
19 beta 4
2012
2014
2016
2017 (Linux)
2017
2019 (Linux)
2019
2022
2025
3.8
3.16
3.27
3.39
3.45
3.53
2.11
2.14
2.28
2.6
2.8
2.18
2024.2 LTS
2025.2 LTS
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
Sakila
no sample DB
Sakila
no sample DB
Sakila
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
HR
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
db<>fiddle Statistics
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
AdventureWorks
no sample DB
AdventureWorks
no sample DB
AdventureWorks
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
no sample DB
run
abort
markdown
clear
donate
feedback
about
By using db<>fiddle, you agree to license everything you submit by
Creative Commons CC0
.
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM'
SELECT TIMESTAMP '1970-01-01 00:00:00.000 UTC' + NUMTODSINTERVAL( 1483228800000 / 1000, 'SECOND' ) AS TIME FROM DUAL
TIME
2017-01-01 00:00:00.000000000 +00:00
CREATE OR REPLACE PACKAGE time_utils IS FUNCTION milliseconds_since_epoch( in_datetime IN TIMESTAMP, in_epoch IN TIMESTAMP DEFAULT TIMESTAMP '1970-01-01 00:00:00' ) RETURN NUMBER; FUNCTION milliseconds_epoch_to_ts ( in_milliseconds IN NUMBER, in_epoch IN TIMESTAMP DEFAULT TIMESTAMP '1970-01-01 00:00:00' ) RETURN TIMESTAMP; END; /
CREATE OR REPLACE PACKAGE BODY time_utils IS -- List of the seconds immediately following leap seconds: leap_seconds CONSTANT SYS.ODCIDATELIST := SYS.ODCIDATELIST( DATE '1972-07-01', DATE '1973-01-01', DATE '1974-01-01', DATE '1975-01-01', DATE '1976-01-01', DATE '1977-01-01', DATE '1978-01-01', DATE '1979-01-01', DATE '1980-01-01', DATE '1981-07-01', DATE '1982-07-01', DATE '1983-07-01', DATE '1985-07-01', DATE '1988-01-01', DATE '1990-01-01', DATE '1991-01-01', DATE '1992-07-01', DATE '1993-07-01', DATE '1994-07-01', DATE '1996-01-01', DATE '1997-07-01', DATE '1999-01-01', DATE '2006-01-01', DATE '2009-01-01', DATE '2012-07-01', DATE '2015-07-01', DATE '2016-01-01' ); HOURS_PER_DAY CONSTANT BINARY_INTEGER := 24; MINUTES_PER_HOUR CONSTANT BINARY_INTEGER := 60; SECONDS_PER_MINUTE CONSTANT BINARY_INTEGER := 60; MILLISECONDS_PER_SECOND CONSTANT BINARY_INTEGER := 1000; MINUTES_PER_DAY CONSTANT BINARY_INTEGER := HOURS_PER_DAY * MINUTES_PER_HOUR; SECONDS_PER_DAY CONSTANT BINARY_INTEGER := MINUTES_PER_DAY * SECONDS_PER_MINUTE; MILLISECONDS_PER_MINUTE CONSTANT BINARY_INTEGER := SECONDS_PER_MINUTE * MILLISECONDS_PER_SECOND; MILLISECONDS_PER_HOUR CONSTANT BINARY_INTEGER := MINUTES_PER_HOUR * MILLISECONDS_PER_MINUTE; MILLISECONDS_PER_DAY CONSTANT BINARY_INTEGER := HOURS_PER_DAY * MILLISECONDS_PER_HOUR; FUNCTION milliseconds_since_epoch( in_datetime IN TIMESTAMP, in_epoch IN TIMESTAMP DEFAULT TIMESTAMP '1970-01-01 00:00:00' ) RETURN NUMBER IS p_leap_milliseconds BINARY_INTEGER := 0; p_diff INTERVAL DAY(9) TO SECOND(3); BEGIN IF in_datetime IS NULL OR in_epoch IS NULL THEN RETURN NULL; END IF; p_diff := in_datetime - in_epoch; IF in_datetime >= in_epoch THEN FOR i IN 1 .. leap_seconds.COUNT LOOP EXIT WHEN in_datetime < leap_seconds(i); IF in_epoch < leap_seconds(i) THEN p_leap_milliseconds := p_leap_milliseconds + MILLISECONDS_PER_SECOND; END IF; END LOOP; ELSE FOR i IN REVERSE 1 .. leap_seconds.COUNT LOOP EXIT WHEN in_datetime > leap_seconds(i); IF in_epoch > leap_seconds(i) THEN p_leap_milliseconds := p_leap_milliseconds - MILLISECONDS_PER_SECOND; END IF; END LOOP; END IF; RETURN MILLISECONDS_PER_SECOND * EXTRACT( SECOND FROM p_diff ) + MILLISECONDS_PER_MINUTE * EXTRACT( MINUTE FROM p_diff ) + MILLISECONDS_PER_HOUR * EXTRACT( HOUR FROM p_diff ) + MILLISECONDS_PER_DAY * EXTRACT( DAY FROM p_diff ) + p_leap_milliseconds; END milliseconds_since_epoch; FUNCTION milliseconds_epoch_to_ts( in_milliseconds IN NUMBER, in_epoch IN TIMESTAMP DEFAULT TIMESTAMP '1970-01-01 00:00:00' ) RETURN TIMESTAMP IS p_datetime TIMESTAMP; BEGIN IF in_milliseconds IS NULL OR in_epoch IS NULL THEN RETURN NULL; END IF; p_datetime := in_epoch + NUMTODSINTERVAL( in_milliseconds / MILLISECONDS_PER_SECOND, 'SECOND' ); IF p_datetime >= in_epoch THEN FOR i IN 1 .. leap_seconds.COUNT LOOP EXIT WHEN p_datetime < leap_seconds(i); IF in_epoch < leap_seconds(i) THEN p_datetime := p_datetime - INTERVAL '1' SECOND; END IF; END LOOP; ELSE FOR i IN REVERSE 1 .. leap_seconds.COUNT LOOP EXIT WHEN p_datetime > leap_seconds(i); IF in_epoch > leap_seconds(i) THEN p_datetime := p_datetime + INTERVAL '1' SECOND; END IF; END LOOP; END IF; RETURN p_datetime; END milliseconds_epoch_to_ts; END; /
SELECT * FROM USER_ERRORS;
SELECT TIME_UTILS.milliseconds_epoch_to_ts( in_milliseconds => 1483228800000, in_epoch => TIMESTAMP '1970-01-01 00:00:00.000' ) AS time FROM DUAL;
TIME
2016-12-31 23:59:33.000000000