Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
CHAPTER 12 ■ DATATYPES 533 ops$tkyte@ORA10G> select numtoyminterval 2 (months_between(dt2,dt1),'month') 3 years_months, 4 dt2-(dt1 + numtoyminterval( trunc(months_between(dt2,dt1)),'month' )) 5 days_hours 6 from (select to_timestamp('29-feb-2000 01:02:03.122000', 7 'dd-mon-yyyy hh24:mi:ss.ff') dt1, 8 to_timestamp('15-mar-2001 11:22:33.000000', 9 'dd-mon-yyyy hh24:mi:ss.ff') dt2 10 from dual ) 11 / dt2-(dt1 + numtoyminterval( trunc(months_between(dt2,dt1)),'month' )) * ERROR at line 4: ORA-01839: date not valid for month specified I personally find this unacceptable. The fact is, though, that by the time you are displaying information with years and months, the fidelity of the TIMESTAMP is destroyed already. A year is not fixed in duration (it may be 365 or 366 days in length) and neither is a month. If you are displaying information with years and months, the loss of microseconds is not relevant; having the information displayed down to the second is more than sufficient at that point. TIMESTAMP WITH TIME ZONE Type The TIMESTAMP WITH TIME ZONE type inherits all of the qualities of the TIMESTAMP type and adds time zone support. The TIMESTAMP WITH TIME ZONE type consumes 13 bytes of storage, with the extra 2 bytes being used to preserve the time zone information. It differs from a TIMESTAMP structurally only by the addition of these 2 bytes: ops$tkyte@ORA10G> create table t 2 ( 3 ts timestamp, 4 ts_tz timestamp with time zone 5 ) 6 / Table created. ops$tkyte@ORA10G> insert into t ( ts, ts_tz ) 2 values ( systimestamp, systimestamp ); 1 row created. ops$tkyte@ORA10G> select * from t; TS TS_TZ ---------------------------- ----------------------------------- 28-JUN-05 01.45.08.087627 PM 28-JUN-05 01.45.08.087627 PM -04:00 ops$tkyte@ORA10G> select dump(ts), dump(ts_tz) from t;
534 CHAPTER 12 ■ DATATYPES DUMP(TS) ------------------------------------------------------------------------------- DUMP(TS_TZ) ------------------------------------------------------------------------------- Typ=180 Len=11: 120,105,6,28,14,46,9,5,57,20,248 Typ=181 Len=13: 120,105,6,28,18,46,9,5,57,20,248,16,60 As you can see, upon retrieval the default TIMESTAMP format included the time zone information (I was on East Coast US time during daylight saving time when this was executed). TIMESTAMP WITH TIME ZONEs store the data in whatever time zone was specified when the data was stored. The time zone becomes part of the data itself. Note how the TIMESTAMP WITH TIME ZONE field stored ...18,46,9... for the hour, minutes, and seconds (in excess-1 notation, so that is 17:45:08), whereas the TIMESTAMP field stored simply ...14,46,9..., which is 13:45:09—the exact time in the string we inserted. The TIMESTAMP WITH TIME ZONE had four hours added to it, in order to store in GMT (also known as UTC) time. The trailing 2 bytes are used upon retrieval to properly adjust the TIMESTAMP value. It is not my intention to cover all of the nuances of time zones here in this book; that is a topic well covered elsewhere. To that end, I’ll just point out that time zone support is more relevant in applications today than ever before. A decade ago, applications were not nearly as global as they are now. In the days before widespread Internet use, applications were many times distributed and decentralized, and the time zone was implicitly based on where the server was located. Today, with large centralized systems being used by people worldwide, the need to track and use time zones is very relevant. Before time zone support was built into a datatype, you had to store the DATE in one column and the time zone information in another, and then it was the application's job to apply functions to convert DATEs from one time zone to another. Now that is the job of the database, and it is able to store data in multiple time zones: ops$tkyte@ORA10G> create table t 2 ( ts1 timestamp with time zone, 3 ts2 timestamp with time zone 4 ) 5 / Table created. ops$tkyte@ORA10G> insert into t (ts1, ts2) 2 values ( timestamp'2005-06-05 17:02:32.212 US/Eastern', 3 timestamp'2005-06-05 17:02:32.212 US/Pacific' ); 1 row created. and perform correct TIMESTAMP arithmetic on them: ops$tkyte@ORA10G> select ts1-ts2 from t; TS1-TS2 --------------------------------------------------------------------------- -000000000 03:00:00.000000
- Page 528 and 529: CHAPTER 11 ■ INDEXES 483 ops$tkyt
- Page 530 and 531: CHAPTER 11 ■ INDEXES 485 This dem
- Page 532 and 533: CHAPTER 11 ■ INDEXES 487 SELECT /
- Page 534 and 535: CHAPTER 12 ■ ■ ■ Datatypes Ch
- Page 536 and 537: CHAPTER 12 ■ DATATYPES 491 • TI
- Page 538 and 539: CHAPTER 12 ■ DATATYPES 493 (in th
- Page 540 and 541: CHAPTER 12 ■ DATATYPES 495 That d
- Page 542 and 543: CHAPTER 12 ■ DATATYPES 497 ops$tk
- Page 544 and 545: CHAPTER 12 ■ DATATYPES 499 Table
- Page 546 and 547: CHAPTER 12 ■ DATATYPES 501 The IN
- Page 548 and 549: CHAPTER 12 ■ DATATYPES 503 ops$tk
- Page 550 and 551: CHAPTER 12 ■ DATATYPES 505 • BI
- Page 552 and 553: CHAPTER 12 ■ DATATYPES 507 NUMBER
- Page 554 and 555: CHAPTER 12 ■ DATATYPES 509 MSG NU
- Page 556 and 557: CHAPTER 12 ■ DATATYPES 511 They a
- Page 558 and 559: CHAPTER 12 ■ DATATYPES 513 ■Not
- Page 560 and 561: CHAPTER 12 ■ DATATYPES 515 Coping
- Page 562 and 563: CHAPTER 12 ■ DATATYPES 517 Note t
- Page 564 and 565: CHAPTER 12 ■ DATATYPES 519 We are
- Page 566 and 567: CHAPTER 12 ■ DATATYPES 521 Format
- Page 568 and 569: CHAPTER 12 ■ DATATYPES 523 ops$tk
- Page 570 and 571: CHAPTER 12 ■ DATATYPES 525 You ca
- Page 572 and 573: CHAPTER 12 ■ DATATYPES 527 month
- Page 574 and 575: CHAPTER 12 ■ DATATYPES 529 DT2-DT
- Page 576 and 577: CHAPTER 12 ■ DATATYPES 531 DT TS
- Page 580 and 581: CHAPTER 12 ■ DATATYPES 535 Since
- Page 582 and 583: CHAPTER 12 ■ DATATYPES 537 ops$tk
- Page 584 and 585: CHAPTER 12 ■ DATATYPES 539 ops$tk
- Page 586 and 587: CHAPTER 12 ■ DATATYPES 541 suppor
- Page 588 and 589: CHAPTER 12 ■ DATATYPES 543 Concep
- Page 590 and 591: CHAPTER 12 ■ DATATYPES 545 We can
- Page 592 and 593: CHAPTER 12 ■ DATATYPES 547 buffer
- Page 594 and 595: CHAPTER 12 ■ DATATYPES 549 Note t
- Page 596 and 597: CHAPTER 12 ■ DATATYPES 551 13 dbm
- Page 598 and 599: CHAPTER 12 ■ DATATYPES 553 equall
- Page 600 and 601: CHAPTER 12 ■ DATATYPES 555 ROWID/
- Page 602 and 603: CHAPTER 13 ■ ■ ■ Partitioning
- Page 604 and 605: CHAPTER 13 ■ PARTITIONING 559 6 (
- Page 606 and 607: CHAPTER 13 ■ PARTITIONING 561 els
- Page 608 and 609: CHAPTER 13 ■ PARTITIONING 563 BIG
- Page 610 and 611: CHAPTER 13 ■ PARTITIONING 565 Enh
- Page 612 and 613: CHAPTER 13 ■ PARTITIONING 567 Tab
- Page 614 and 615: CHAPTER 13 ■ PARTITIONING 569 tha
- Page 616 and 617: CHAPTER 13 ■ PARTITIONING 571 PAR
- Page 618 and 619: CHAPTER 13 ■ PARTITIONING 573 35
- Page 620 and 621: CHAPTER 13 ■ PARTITIONING 575 If
- Page 622 and 623: CHAPTER 13 ■ PARTITIONING 577 We
- Page 624 and 625: CHAPTER 13 ■ PARTITIONING 579 14
- Page 626 and 627: CHAPTER 13 ■ PARTITIONING 581 ops
534<br />
CHAPTER 12 ■ DATATYPES<br />
DUMP(TS)<br />
-------------------------------------------------------------------------------<br />
DUMP(TS_TZ)<br />
-------------------------------------------------------------------------------<br />
Typ=180 Len=11: 120,105,6,28,14,46,9,5,57,20,248<br />
Typ=181 Len=13: 120,105,6,28,18,46,9,5,57,20,248,16,60<br />
As you can see, upon retrieval the default TIMESTAMP format included the time zone information<br />
(I was on East Coast US time during daylight saving time when this was executed).<br />
TIMESTAMP WITH TIME ZONEs store the data in whatever time zone was specified when the<br />
data was stored. The time zone becomes part of the data itself. Note how the TIMESTAMP WITH<br />
TIME ZONE field stored ...18,46,9... for the hour, minutes, <strong>and</strong> seconds (in excess-1 notation,<br />
so that is 17:45:08), whereas the TIMESTAMP field stored simply ...14,46,9..., which is<br />
13:45:09—the exact time in the string we inserted. The TIMESTAMP WITH TIME ZONE had four<br />
hours added to it, in order to store in GMT (also known as UTC) time. The trailing 2 bytes are<br />
used upon retrieval to properly adjust the TIMESTAMP value.<br />
It is not my intention to cover all of the nuances of time zones here in this book; that is a<br />
topic well covered elsewhere. To that end, I’ll just point out that time zone support is more relevant<br />
in applications today than ever before. A decade ago, applications were not nearly as<br />
global as they are now. In the days before widespread Internet use, applications were many<br />
times distributed <strong>and</strong> decentralized, <strong>and</strong> the time zone was implicitly based on where the<br />
server was located. Today, with large centralized systems being used by people worldwide, the<br />
need to track <strong>and</strong> use time zones is very relevant.<br />
Before time zone support was built into a datatype, you had to store the DATE in one column<br />
<strong>and</strong> the time zone information in another, <strong>and</strong> then it was the application's job to apply<br />
functions to convert DATEs from one time zone to another. Now that is the job of the database,<br />
<strong>and</strong> it is able to store data in multiple time zones:<br />
ops$tkyte@ORA10G> create table t<br />
2 ( ts1 timestamp with time zone,<br />
3 ts2 timestamp with time zone<br />
4 )<br />
5 /<br />
Table created.<br />
ops$tkyte@ORA10G> insert into t (ts1, ts2)<br />
2 values ( timestamp'2005-06-05 17:02:32.212 US/Eastern',<br />
3 timestamp'2005-06-05 17:02:32.212 US/Pacific' );<br />
1 row created.<br />
<strong>and</strong> perform correct TIMESTAMP arithmetic on them:<br />
ops$tkyte@ORA10G> select ts1-ts2 from t;<br />
TS1-TS2<br />
---------------------------------------------------------------------------<br />
-000000000 03:00:00.000000