20

How are dates stored in Oracle? For example I know most systems use Epoch time to determine what time it is. By calculating how many seconds away from January 1st 1970. Does Oracle do this as well?

The reason I am asking this is I noticed if you take two dates in Oracle and subtract them you get a floating point of how many days are between.

Example

(Sysdate - dateColumn)

would return something like this (depending on the time)

3.32453703703703703703703703703703703704

Now is Oracle doing the conversion and spitting that format out, or does Oracle store dates with how many days it is away from a certain time frame? (Like Epoch time)

Halfwarr
  • 7,853
  • 6
  • 33
  • 51
  • I wonder how many bits you'd need to store Unix timestamps in the -4713 to 9999 range... – Álvaro González Nov 26 '12 at 15:52
  • 3
    @AlvaroGonzalez: that would be 14711 years. How many seconds in that many years? If we say there are 365.25 days in a year then there are 31557600 seconds in a year, which means there are 464,243,853,600 seconds in 14711 years. So a 39 bit value (max = 549,755,813,888) would handle it. A 64 bit number would handle it for the forseeable (out to roughly the year 584,542,041,377) future :-). – Bob Jarvis - Слава Україні Apr 14 '16 at 19:01

3 Answers3

29

There are two types 12 and 13

http://oraclesniplets.tumblr.com/post/1179958393/my-oracle-support-oracle-database-69028-1

Type 13

select dump(sysdate) from dual;
Typ=13 Len=8: 220,7,11,26,16,41,9,0

The format of the date datatype is

Byte 1 - Base 256 year modifier : 220
2      - Base 256 year : 256 * 7 = 1792 + 220 = 2012
3      - Month : 11
4      - Day : 26
5      - Hours : 16
6      - Minutes : 41
7      - Seconds : 09
8      - Unused

2012-11-26 16:41:09

Type 12

select dump(begindate) from tab;
Typ=12 Len=7: 100,112,2,7,1,1,1

The format of the date datatype is

byte 1 - century (excess 100)  100 - 100 = 00
byte 2 - year (excess 100)  112 - 100 = 12
byte 3 - month = 2
byte 4 - day = 7
byte 5 - hour (excess 1) 1 - 1 = 0
byte 6 - minute (excess 1) 1 - 1 = 0
byte 7 - seconds (excess 1) 1 - 1 = 0

0012-02-07 00:00:00

Rob van Laarhoven
  • 8,737
  • 2
  • 31
  • 49
6

From the manual at http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements001.htm#sthref151

For each DATE value, Oracle stores the following information: year, month, day, hour, minute, and second

So apparently it's not storing an epoch value which is also confirmed by this chapter of the manual:

The database stores dates internally as numbers. Dates are stored in fixed-length fields of 7 bytes each, corresponding to century, year, month, day, hour, minute, and second

  • Very interesting, Thank You! I was sorta hoping it used Julian date for storing the date. This method probably makes more sense anyway! – Halfwarr Nov 26 '12 at 16:04
  • @Halfwarr: why do you care how it's stored? That does not matter at all. –  Nov 26 '12 at 17:06
  • Just wanted to know, no real reason. I was just curious how they are stored because I was working with them. You can never have enough random knowledge ;) – Halfwarr Nov 26 '12 at 18:29
6

How are dates stored in Oracle?

The two data types 12 and 13 are for two different purposes.

  • Type 12 - Dates stored in table
  • Type 13 - Date returned by internal date functions like SYSDATE/CURRENT_DATE, also when converting a string literal into date using TO_DATE or ANSI Date literal DATE 'YYYY-MM-DD'.

Test cases:

Basic table setup for type 12:

SQL> CREATE TABLE t(col DATE);

Table created.

SQL> INSERT INTO t SELECT SYSDATE FROM dual;

1 row created.

SQL> COMMIT;

Commit complete.

Check the different cases:

SQL> SELECT DUMP(col) FROM t;

DUMP(COL)
--------------------------------------------------------------------------------
Typ=12 Len=7: 120,116,3,17,18,6,55

SQL> SELECT DUMP(SYSDATE) FROM dual;

DUMP(SYSDATE)
--------------------------------------------------------------------------------
Typ=13 Len=8: 224,7,3,17,17,5,54,0

SQL> SELECT DUMP(CURRENT_DATE) FROM dual;

DUMP(CURRENT_DATE)
--------------------------------------------------------------------------------
Typ=13 Len=8: 224,7,3,17,17,14,20,0

SQL> SELECT DUMP(TO_DATE('17-DEC-1980 12:12:12','DD-MON-YYYY HH24:MI:SS'))  FROM dual;

DUMP(TO_DATE('17-DEC-198012:12:12','
------------------------------------
Typ=13 Len=8: 188,7,12,17,12,12,12,0

Using ANSI Date literal, just like TO_DATE:

SQL> SELECT DUMP(DATE '2016-03-17') FROM dual;

DUMP(DATE'2016-03-17')
--------------------------------
Typ=13 Len=8: 224,7,3,17,0,0,0,0

SQL> INSERT INTO t SELECT to_date('17-DEC-1980 12:13:14','DD-MON-YYYY HH24:MI:SS') FROM dual;

1 row created.

SQL> COMMIT;

Commit complete.

SQL> SELECT DUMP(col) FROM t;

DUMP(COL)
--------------------------------------------------------------------------------
Typ=12 Len=7: 120,116,3,17,18,6,55
Typ=12 Len=7: 119,180,12,17,13,14,15

SQL>

As you can see, while storing a date in the table, it uses type 12. The second type 13 is used when converting a string literal into date using date functions or when date returned by internal date functions like SYSDATE/CURRENT_DATE.

Lalit Kumar B
  • 47,486
  • 13
  • 97
  • 124