9.8. Funções e operadores para data e hora

A Tabela 9-28 mostra as funções disponíveis para processamento de valor de data e de hora. Os detalhes são mostrados nas próximas subseções. A Tabela 9-27 mostra o comportamento dos operadores aritméticos básicos (+, *, etc.). Para as funções de formatação consulte a Seção 9.7 . É necessário estar familiarizado com os tipos de dado para data e hora presentes na Seção 8.5 .

Todas as funções e operadores descritos abaixo, que recebem os tipos time ou timestamp como entrada, estão presentes em duas formas: uma que recebe time with time zone ou timestamp with time zone, e outra que recebe time without time zone ou timestamp without time zone. Para abreviar, estas formas não são mostradas em separado.

Tabela 9-27. Operadores para data e hora

Operador Exemplo Resultado
+ date '2001-09-28' + integer '7' date '2001-10-05'
+ date '2001-09-28' + interval '1 hour' timestamp '2001-09-28 01:00'
+ date '2001-09-28' + time '03:00' timestamp '2001-09-28 03:00'
+ time '03:00' + date '2001-09-28' timestamp '2001-09-28 03:00'
+ interval '1 day' + interval '1 hour' interval '1 day 01:00'
+ timestamp '2001-09-28 01:00' + interval '23 hours' timestamp '2001-09-29 00:00'
+ time '01:00' + interval '3 hours' time '04:00'
+ interval '3 hours' + time '01:00' time '04:00'
- - interval '23 hours' interval '-23:00'
- date '2001-10-01' - date '2001-09-28' integer '3'
- date '2001-10-01' - integer '7' date '2001-09-24'
- date '2001-09-28' - interval '1 hour' timestamp '2001-09-27 23:00'
- time '05:00' - time '03:00' interval '02:00'
- time '05:00' - interval '2 hours' time '03:00'
- timestamp '2001-09-28 23:00' - interval '23 hours' timestamp '2001-09-28 00:00'
- interval '1 day' - interval '1 hour' interval '23:00'
- interval '2 hours' - time '05:00' time '03:00'
- timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00' interval '1 day 15:00'
* double precision '3.5' * interval '1 hour' interval '03:30'
* interval '1 hour' * double precision '3.5' interval '03:30'
/ interval '1 hour' / double precision '1.5' interval '00:40'

Tabela 9-28. Funções para data e hora

Função Tipo retornado Descrição Exemplo Resultado
age(timestamp) interval Subtrai de current_date age(timestamp '1957-06-13') 43 years 8 mons 3 days
age(timestamp, timestamp) interval Subtrai os argumentos, produzindo um resultado "simbólico" que utiliza anos e meses age('2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days
current_date date Data de hoje; veja a Seção 9.8.4    
current_time time with time zone Hora do dia; veja a Seção 9.8.4    
current_timestamp timestamp with time zone Data e hora; veja a Seção 9.8.4    
date_part(text, timestamp) double precision Retorna subcampo (equivale ao extract); veja a Seção 9.8.1 date_part('hour', timestamp '2001-02-16 20:38:40') 20
date_part(text, interval) double precision Retorna subcampo (equivale ao extract); veja a Seção 9.8.1 date_part('month', interval '2 years 3 months') 3
date_trunc(text, timestamp) timestamp Trunca na precisão especificada; veja a Seção 9.8.2 date_trunc('hour', timestamp '2001-02-16 20:38:40') 2001-02-16 20:00:00
extract(campo from timestamp) double precision Retorna subcampo; veja a Seção 9.8.1 extract(hour from timestamp '2001-02-16 20:38:40') 20
extract(campo from interval) double precision Retorna subcampo; veja a Seção 9.8.1 extract(month from interval '2 years 3 months') 3
isfinite(timestamp) boolean Testa carimbo do tempo finito (diferente de infinito) isfinite(timestamp '2001-02-16 21:28:30') true
isfinite(interval) boolean Testa intervalo finito isfinite(interval '4 hours') true
localtime time Hora do dia; veja a Seção 9.8.4    
localtimestamp timestamp Data e hora; veja a Seção 9.8.4    
now() timestamp with time zone Data e hora corrente (equivale ao current_timestamp); veja a Seção 9.8.4    
timeofday() text Data e hora corrente; veja a Seção 9.8.4    

Além destas funções, é suportado o operador OVERLAPS do SQL:

( inicio1, fim1 ) OVERLAPS ( inicio2, fim2 )
( inicio1, duração1 ) OVERLAPS ( inicio2, duração2 )

O resultado desta expressão é verdade quando dois períodos de tempo (definidos por seus pontos limites) se sobrepõem, e falso quando não se sobrepõem. Os pontos limites podem ser especificados como pares de datas, horas, ou carimbo do tempo; ou como data, hora ou carimbo do tempo seguido por um intervalo.

SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Resultado: verdade
SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
       (DATE '2001-10-30', DATE '2002-10-30');
Resultado: falso

9.8.1. Funções EXTRACT e date_part

EXTRACT (campo FROM fonte)

A função extract retorna subcampos dos valores de data e hora, como o ano ou a hora. A fonte deve ser uma expressão de valor do tipo timestamp ou interval (As expressões do tipo date ou time são convertidas em timestamp, o que possibilita utilizá-las da mesma forma). O campo é um identificador, ou uma cadeia de caracteres, que seleciona o campo a ser extraído do valor fonte. A função extract retorna valores do tipo double precision. Abaixo estão mostrados os nomes de campo válidos:

century
O campo ano dividido por 100
SELECT extract(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 20
Deve ser observado que o resultado para o campo século é simplesmente o campo ano dividido por 100, e não a definição habitual que coloca a maior parte dos anos de 1900 no século vinte.
day
O campo dia (do mês) (1 - 31)
SELECT extract(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 16
decade
O campo ano dividido por 10
SELECT extract(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 200
dow
O dia da semana (0 - 6; Domingo é 0) (para valores timestamp apenas)
SELECT extract(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 5
Deve ser observado que a numeração do dia da semana da função extract (0 a 6) é diferente da numeração do dia da semana da função to_char (1 a 7).
=> SELECT extract(DOW FROM TIMESTAMP '2005-08-14 20:38:40') AS Domingo;

 domingo
---------
       0
(1 linha)

=> SELECT to_char(TIMESTAMP '2005-08-14 20:38:40','D') AS Domingo;

 domingo
---------
 1
(1 linha)

=> SELECT extract(DOW FROM TIMESTAMP '2005-08-20 20:38:40') AS Sábado;

 sábado
--------
      6
(1 linha)

=> SELECT to_char(TIMESTAMP '2005-08-20 20:38:40','D') AS Sábado;

 sábado
--------
 7
(1 linha)
doy
O dia do ano (1 - 365/366) (para valores timestamp apenas)
SELECT extract(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 47
Deve ser observado que a numeração do dia do ano da função extract (1 a 366) é igual a numeração do dia do ano da função to_char (1 a 366).
=> SELECT extract(DOY FROM TIMESTAMP '2004-12-31 23:59:59') AS dia;

 dia
-----
 366
(1 linha)

=> SELECT to_char(TIMESTAMP '2004-12-31 23:59:59', 'DDD') AS dia;

 dia
-----
 366
(1 linha)
epoch
Para valores date e timestamp, o número de segundos desde 1970-01-01 00:00:00-00 (pode ser negativo); para valores interval, o número total de segundos do intervalo
SELECT extract(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-08');
Resultado: 982384720

SELECT extract(EPOCH FROM INTERVAL '5 days 3 hours');
Resultado: 442800
hour
O campo hora (0 - 23)
SELECT extract(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 20
microseconds
O campo segundos, incluindo a parte fracionária, multiplicado por 1 milhão (1.000.000). Deve ser observado que inclui os segundos decorridos, e não apenas a fração de segundos.
SELECT extract(MICROSECONDS FROM TIME '17:12:28.5');
Resultado: 28500000
millennium
O campo ano dividido por 1 000
SELECT extract(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 2
Deve ser observado que o resultado para o campo milênio é simplesmente o campo ano dividido por 1000, e não a definição habitual que coloca os anos de 1900 no segundo milênio.
milliseconds
O campo segundos, incluindo a parte fracionária, multiplicado por mil (1.000). Deve ser observado que inclui os segundos decorridos, e não apenas a fração de segundos.
SELECT extract(MILLISECONDS FROM TIME '17:12:28.5');
Resultado: 28500
minute
O campo minutos (0 - 59)
SELECT extract(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 38
month
Para valores timestamp, o número do mês do ano dentro do ano (1 - 12); para valores interval, o número de meses, módulo 12 (0 - 11)
SELECT extract(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 2

SELECT extract(MONTH FROM INTERVAL '2 years 3 months');
Resultado: 3

SELECT extract(MONTH FROM INTERVAL '2 years 13 months');
Resultado: 1
quarter
O trimestre do ano (1 - 4) onde o dia se encontra (para valores timestamp apenas)
SELECT extract(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 1
second
O campo segundos, incluindo a parte fracionária (0 - 59) [1] [2]
SELECT extract(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 40

SELECT extract(SECOND FROM TIME '17:12:28.5');
Resultado: 28.5
timezone
O deslocamento da zona horária em relação à UTC, medido em segundos. Os valores positivos correspondem às zonas horárias a leste da UTC, e os valores negativos correspondem às zonas horárias a oeste da UTC. [3]
timezone_hour
O componente hora do deslocamento da zona horária
timezone_minute
O componente minuto do deslocamento da zona horária
week
O número da semana do ano onde o dia se encontra. Por definição (ISO 8601), a primeira semana do ano contém o dia 4 de janeiro deste ano; a semana ISO-8601 começa na segunda-feira. Em outras palavras, a primeira quinta-feira do ano está na primeira semana do ano. (apenas para valores timestamp)
SELECT extract(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 7
year
O campo ano. Deve-se ter em mente que não existe o ano 0 DC e, portanto, subtrair anos AC de DC deve ser feito com cautela.
SELECT extract(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 2001

A função extract é voltada principalmente para o processamento computacional. Para formatar valores de data e hora para exibição, veja a Seção 9.7 .

A função date_part é modelada segundo a função equivalente tradicional do Ingres à função extract do padrão SQL:

date_part('campo', fonte)

Deve ser observado que, neste caso, o parâmetro campo deve ser um valor cadeia de caracteres, e não um nome. Os nomes de campo válidos para date_part são os mesmos da função extract.

SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
Resultado: 16

SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
Resultado: 4

9.8.2. date_trunc

A função date_trunc é conceitualmente similar à função trunc para números.

date_trunc('campo', fonte)

fonte é uma expressão de valor do tipo timestamp ou interval (valores do tipo date e time são convertidos automaticamente em timestamp ou interval, respectivamente). O campo seleciona a precisão a ser utilizada para truncar o valor da entrada. O valor retornado é do tipo timestamp ou interval, com todos os campos menos significativos do que valor selecionado tornados zero (ou um, para o dia do mês).

Os valores válidos para campo são:

microseconds
milliseconds
second
minute
hour
day
month
year
decade
century
millennium

Exemplos:

SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
Resultado: 2001-02-16 20:00:00

SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
Resultado: 2001-01-01 00:00:00

9.8.3. AT TIME ZONE

A construção AT TIME ZONE permite a conversão do carimbo do tempo para uma zona horária diferente. A Tabela 9-29 mostra suas variantes.

Tabela 9-29. Variantes de AT TIME ZONE

Expressão Tipo Retornado Descrição
timestamp without time zone AT TIME ZONE zona timestamp with time zone Converte hora local de uma determinada zona horária para UTC
timestamp with time zone AT TIME ZONE zona timestamp without time zone Converte de UTC para a hora local em uma determinada zona horária
time with time zone AT TIME ZONE zona time with time zone Converte hora local entre zonas horárias

Nestas expressões, a zona da zona horária desejada, pode ser especificada tanto por meio de um texto em uma cadeia de caracteres (por exemplo, 'PST'), quanto por um intervalo (por exemplo, INTERVAL '-08:00').

Exemplos (supondo que a zona horária local seja PST8PDT):

SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST';
Resultado: 2001-02-16 19:38:40-08

SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST';
Resultado: 2001-02-16 18:38:40

O primeiro exemplo recebe um carimbo do tempo sem zona horária e o interpreta como hora MST (UTC-7) para produzir um carimbo do tempo UTC, o qual é então rotacionado para PST (UTC-8) para ser exibido. O segundo exemplo recebe um carimbo do tempo especificado em EST (UTC-5) e converte para hora local MST (UTC-7).

A função timezone(zona, carimbo_do_tempo) equivale à construção em conformidade com o padrão SQL carimbo_do_tempo AT TIME ZONE zona.

9.8.4. Data e hora corrente

Estão disponíveis as seguintes funções para obter a data e hora corrente:

CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME ( precisão )
CURRENT_TIMESTAMP ( precisão )
LOCALTIME
LOCALTIMESTAMP
LOCALTIME ( precisão )
LOCALTIMESTAMP ( precisão )

CURRENT_TIME e CURRENT_TIMESTAMP retornam valores com zona horária; LOCALTIME e LOCALTIMESTAMP retornam valores sem zona horária.

CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME e LOCALTIMESTAMP podem, opcionalmente, receber o parâmetro precisão fazendo o resultado ser arredondado nesta quantidade de dígitos fracionários no campo de segundos. Sem o parâmetro de precisão, o resultado é produzido com toda a precisão disponível.

Nota: Antes do PostgreSQL versão 7.2, os parâmetros de precisão não estavam implementados, e o resultado era sempre retornado em segundos inteiros.

Alguns exemplos:

SELECT CURRENT_TIME;
Resultado: 14:39:53.662522-05

SELECT CURRENT_DATE;
Resultado: 2001-12-23

SELECT CURRENT_TIMESTAMP;
Resultado: 2001-12-23 14:39:53.662522-05

SELECT CURRENT_TIMESTAMP(2);
Resultado: 2001-12-23 14:39:53.66-05

SELECT LOCALTIMESTAMP;
Resultado: 2001-12-23 14:39:53.662522

A função now() é o equivalente tradicional do PostgreSQL para CURRENT_TIMESTAMP.

Também existe a função timeofday(), que por motivos históricos retorna uma cadeia de caracteres do tipo text, e não um valor do tipo timestamp:

SELECT timeofday();
Resultado: Sat Feb 17 19:07:32.000126 2001 EST

É importante saber que CURRENT_TIMESTAMP, e as funções relacionadas, retornam a data e hora do começo da transação corrente; seus valores não mudam durante a transação. Isto é considerado uma funcionalidade: o objetivo é permitir que a transação possua uma noção consistente do tempo "corrente", de forma que várias modificações dentro da mesma transação compartilhem o mesmo carimbo do tempo. A função timeofday() retorna a hora do relógio, avançando durante as transações.

Nota: Outros sistemas de banco de dados podem avançar estes valores com mais freqüência.

Todos os tipos de dado para data e hora também aceitam o valor literal especial now para especificar a data e hora corrente. Portanto, os três comandos abaixo retornam o mesmo resultado:

SELECT CURRENT_TIMESTAMP;
SELECT now();
SELECT TIMESTAMP 'now'; -- incorreto para uso com DEFAULT

Dica: Não se utiliza a terceira forma ao especificar a cláusula DEFAULT na criação da tabela. O sistema converte now em timestamp tão logo a constante é analisada e, portanto, quando o valor padrão for utilizado será utilizada a hora da criação da tabela! As duas primeiras formas não são avaliadas até que o valor padrão seja utilizado, porque são chamadas de função. Assim sendo, as duas primeiras formas fornecem o comportamento desejado quando o padrão for a hora de inserção da linha.

9.8.5. Comparação entre o PostgreSQL, o Oracle, o SQL Server e o DB2

Nota: Seção escrita pelo tradutor, não fazendo parte do manual original.

Esta seção tem por finalidade comparar, através de exemplos práticos, as funções e operadores para data e hora do PostgreSQL, do Oracle, do SQL Server e do DB2.

Exemplo 9-8. Utilização de INTERVAL

Abaixo estão mostrados exemplos comparando a utilização de INTERVAL no PostgreSQL e no Oracle. Veja também Interval Literals .

PostgreSQL 7.4.1:

=> SELECT INTERVAL'20 DAY' - INTERVAL'240 HOUR' AS intervalo;

 intervalo
-----------
 10 days
(1 linha)

=> SELECT INTERVAL '4 DAYS 5 HOURS 12 MINUTES';

    interval
-----------------
 4 days 05:12:00
(1 linha)

Oracle 10g:

SQL> SELECT INTERVAL'20' DAY - INTERVAL'240' HOUR(3) FROM sys.dual;

INTERVAL'20'DAY-INTERVAL'240'HOUR(3)
------------------------------------
+000000010 00:00:00.000000000

SQL> SELECT INTERVAL '4 5:12' DAY TO MINUTE  FROM sys.dual;

INTERVAL'45:12'DAYTOMINUTE
--------------------------
+04 05:12:00

Exemplo 9-9. Número de dias entre duas datas

Abaixo estão mostrados exemplos de funções do PostgreSQL, do SQL Server, do Oracle e do DB2, para obter o número de dias entre duas datas. Veja também Getting the difference between Dates , DB2 Basics: Fun with Dates and Times e SQL Server, DATEDIFF

PostgreSQL 7.4.1:

=> SELECT date('1950-07-16') - date('1949-11-21') AS dias;

 dias
------
  237
(1 linha)

SQL Server 2000:

SELECT datediff(DAY, convert(datetime,'1949-11-21',120), convert(datetime,'1950-07-16',120)) AS dias

dias
----
237
(1 row(s) affected)

Oracle 10g:

SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';

SQL> SELECT to_date('1950-07-16') - to_date('1949-11-21') AS dias FROM sys.dual;

      DIAS
----------
       237

DB2 8.1:

DB2SQL92> SELECT days(date('1950-07-16'))- days(date('1949-11-21')) AS dias FROM sysibm.sysdummy1;

DIAS
-------------
        237

Exemplo 9-10. Obtenção do dia do mês

Abaixo estão mostrados exemplos de funções do PostgreSQL, do SQL Server, do Oracle e do DB2, para obter o dia do mês. Veja também TO_CHAR (datetime) no Oracle , DAY no DB2 e SQL Server Date and Time Functions

PostgreSQL 7.4.1:

=> SELECT date_part('day',CURRENT_TIMESTAMP) AS dia;

 dia
-----
  14
(1 linha)

=> SELECT extract(DAY FROM CURRENT_TIMESTAMP) AS dia;

 dia
-----
  14
(1 linha)

=> SELECT to_char(CURRENT_TIMESTAMP,'DD') AS dia;

 dia
-----
 14
(1 linha)

SQL Server 2000:

SELECT datepart(DAY, CURRENT_TIMESTAMP) AS dia

dia
---
14
(1 row(s) affected)

SELECT day(CURRENT_TIMESTAMP) AS dia

dia
---
14
(1 row(s) affected)

Oracle 10g:

SQL> SELECT to_char(CURRENT_TIMESTAMP,'DD') AS dia FROM sys.dual;

DI
--
14

SQL> SELECT extract(DAY FROM CURRENT_TIMESTAMP) AS dia FROM sys.dual;

DI
--
14

DB2 8.1:

DB2SQL92> SELECT day(CURRENT_TIMESTAMP) FROM sysibm.sysdummy1;

1
-------------
         14

Exemplo 9-11. Utilização das funções para data e hora corrente

Abaixo estão mostrados exemplos comparando a utilização das funções que retornam a data e hora corrente no PostgreSQL, no SQL Server, no Oracle e no DB2. [4] . Veja também CURRENT_TIMESTAMP no Oracle , CURRENT_TIMESTAMP no SQL Server e CURRENT_TIMESTAMP no DB2 .

Como o PostgreSQL e o DB2 foram executados no Linux, enquanto o SQL Server e o Oracle foram executados no Windows 2000, deve ser observado que a precisão da fração de segundos varia.

PostgreSQL 7.4.1:

=> SELECT CURRENT_DATE;

    date
------------
 2005-03-04
(1 linha)

=> SELECT CURRENT_TIME;

       timetz
--------------------
 16:42:07.33-03
(1 linha)

=> SELECT CURRENT_TIMESTAMP;

          timestamptz
-------------------------------
 2005-03-23 08:54:49.150806-03
(1 linha)

=> SELECT CURRENT_TIME(0);

   timetz
-------------
 08:55:17-03
(1 linha)

=> SELECT CURRENT_TIMESTAMP(0);

      timestamptz
------------------------
 2005-03-23 08:55:41-03
(1 linha)

=> SELECT LOCALTIME AS agora;

      agora
-----------------
 08:56:04.343581
(1 linha)

=> SELECT LOCALTIMESTAMP;

         timestamp
----------------------------
 2005-03-23 08:56:24.708273
(1 linha)

=> SELECT LOCALTIME (0) AS agora;

  agora
----------
 08:56:55
(1 linha)

=> SELECT LOCALTIMESTAMP (0) AS agora;

        agora
---------------------
 2005-03-23 08:57:29
(1 linha)

=> SELECT CURRENT_TIMESTAMP AT TIME ZONE 'UTC' AS UTC;

            utc
----------------------------
 2005-03-23 11:57:57.303915
(1 linha)

=> SELECT now();

              now
-------------------------------
 2005-03-23 08:58:19.025323-03
(1 linha)

=> SELECT timeofday();

              timeofday
-------------------------------------
 Wed Mar 23 08:58:39.378803 2005 BRT
(1 linha)

=> SELECT to_char(CURRENT_TIMESTAMP, 'DD-MM-YYYY HH24:MI:SS') AS agora;

        agora
---------------------
 23-03-2005 08:59:03
(1 linha)

SQL Server 2000:

SELECT CURRENT_TIMESTAMP AS agora

agora
-----------------------
2005-03-04 16:39:51.207
(1 row(s) affected)

SELECT getdate() AS agora

agora
-----------------------
2005-03-04 16:39:51.207
(1 row(s) affected)

SELECT getutcdate() AS UTC

UTC
-----------------------
2005-03-04 19:39:51.207
(1 row(s) affected)

SELECT convert(VARCHAR, CURRENT_TIMESTAMP, 121) AS agora

agora
-----------------------
2005-03-04 16:39:51.207
(1 row(s) affected)

Oracle 10g:

SQL> ALTER SESSION SET TIME_ZONE = local;
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
SQL> ALTER SESSION SET NLS_TIMESTAMP_FORMAT  = 'YYYY-MM-DD HH24:MI:SS.FF';
SQL> ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT  = 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM';

SQL> SELECT CURRENT_DATE FROM sys.dual;

CURRENT_DA
----------
2005-03-26

SQL> SELECT CURRENT_TIMESTAMP FROM sys.dual;

CURRENT_TIMESTAMP
---------------------------------
2005-03-26 17:31:33.934000 -03:00

SQL> SELECT CURRENT_TIMESTAMP(0) FROM sys.dual;

CURRENT_TIMESTAMP(0)
---------------------------
2005-03-26 17:31:34. -03:00

SQL> SELECT LOCALTIMESTAMP FROM sys.dual;

LOCALTIMESTAMP
--------------------------
2005-03-26 17:31:33.954000

SQL> SELECT LOCALTIMESTAMP (0) FROM sys.dual;

LOCALTIMESTAMP(0)
--------------------
2005-03-26 17:31:34.

SQL> SELECT CURRENT_TIMESTAMP AT TIME ZONE 'UTC' AS UTC FROM sys.dual;

UTC
---------------------------------
2005-03-26 20:31:33.984000 +00:00

SQL> SELECT to_char(CURRENT_TIMESTAMP, 'DD-MM-YYYY HH24:MI:SS') AS agora FROM sys.dual;

AGORA
-------------------
26-03-2005 17:31:33

DB2 8.1:

DB2SQL92> SELECT CURRENT_DATE AS data FROM sysibm.sysdummy1;

DATA
------------
26/03/2005

DB2SQL92> SELECT CURRENT DATE AS data FROM sysibm.sysdummy1;

DATA
------------
26/03/2005

DB2SQL92> SELECT CURRENT_TIME AS hora FROM sysibm.sysdummy1;

HORA
----------
21:55:05

DB2SQL92> SELECT CURRENT TIME AS hora FROM sysibm.sysdummy1;

HORA
----------
21:55:25

DB2SQL92> SELECT CURRENT_TIMESTAMP AS agora FROM sysibm.sysdummy1;

AGORA
----------------------------
2005-03-26-21.55.47.195177

DB2SQL92> SELECT CURRENT TIMESTAMP AS agora FROM sysibm.sysdummy1;

AGORA
----------------------------
2005-03-26-21.56.13.294096

DB2SQL92> SELECT CURRENT TIMESTAMP - MICROSECOND (CURRENT TIMESTAMP) MICROSECONDS
DB2SQL92>       AS "CURRENT_TIMESTAMP(0)" FROM sysibm.sysdummy1;

CURRENT_TIMESTAMP(0)
----------------------------
2005-03-26-21.56.42.000000

DB2SQL92> SELECT CURRENT TIMESTAMP - CURRENT TIMEZONE AS utc FROM sysibm.sysdummy1;

UTC
----------------------------
2005-03-27-00.57.19.704003

Exemplo 9-12. Tipo de dado timestamp

Abaixo são mostrados exemplos comparando a utilização do tipo de dado timestamp no PostgreSQL, no SQL Server, no Oracle e no DB2.

PostgreSQL 7.4.1:

=> SELECT TIMESTAMP '1999-01-01 12:34:56' AS timestamp;

      timestamp
---------------------
 1999-01-01 12:34:56
(1 linha)

=> SELECT cast('1999-01-01 12:34:56' AS TIMESTAMP) AS timestamp;

      timestamp
---------------------
 1999-01-01 12:34:56
(1 linha)

SQL Server 2000:

SELECT cast('1999-01-01 12:34:56' AS datetime) AS timestamp

timestamp
-----------------------
1999-01-01 12:34:56.000
(1 row(s) affected)

SELECT convert(datetime,'1999-01-01 12:34:56',120) AS timestamp

timestamp
-----------------------
1999-01-01 12:34:56.000
(1 row(s) affected)

Oracle 10g:

SQL> ALTER SESSION SET TIME_ZONE = local;
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
SQL> ALTER SESSION SET NLS_TIMESTAMP_FORMAT  = 'YYYY-MM-DD HH24:MI:SS.FF';
SQL> ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT  = 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM';

SQL> SELECT TIMESTAMP '1999-01-01 12:34:56' AS timestamp FROM sys.dual;

TIMESTAMP
-----------------------------
1999-01-01 12:34:56.000000000

SQL> SELECT cast('1999-01-01 12:34:56' AS TIMESTAMP) AS timestamp FROM sys.dual;

TIMESTAMP
--------------------------
1999-01-01 12:34:56.000000

DB2 8.1:

DB2SQL92> SELECT timestamp('1999-01-01','12.34.56') AS timestamp FROM sysibm.sysdummy1;

TIMESTAMP
----------------------------
1999-01-01-12.34.56.000000

DB2SQL92> SELECT cast('1999-01-01 12:34:56' AS TIMESTAMP) AS timestamp FROM sysibm.sysdummy1;

TIMESTAMP
----------------------------
1999-01-01-12.34.56.000000

Exemplo 9-13. Somar dias e horas a uma data

Abaixo são mostrados exemplos de aritmética com datas, somando 30 dias a uma data sem hora, 30 dias a uma data com hora, e 3 dias e 3 horas ao carimbo do tempo corrente, no PostgreSQL, no Oracle, no SQL Server e no DB2. [5]

PostgreSQL 7.4.1:

=> SELECT cast('2004-07-16' AS date) + interval'30 days' AS data;

        data
---------------------
 2004-08-15 00:00:00
(1 linha)

=> SELECT cast('2004-07-16 15:00:00' AS timestamp) + interval'30 days' AS data;

        data
---------------------
 2004-08-15 15:00:00
(1 linha)

=> SELECT current_timestamp as agora,
-> current_timestamp + interval'3 days 3 hours' AS depois;

             agora             |            depois
-------------------------------+-------------------------------
 2005-04-01 08:16:44.029386-03 | 2005-04-04 11:16:44.029386-03
(1 linha)

SQL Server 2000:

SELECT dateadd(DAY,30,convert(smalldatetime,'2004-07-16',120)) as data

data
-------------------
2004-08-15 00:00:00
(1 row(s) affected)

SELECT dateadd(DAY,30,convert(datetime,'2004-07-16 15:00:00',120)) as data

data
-----------------------
2004-08-15 15:00:00.000
(1 row(s) affected)

SELECT current_timestamp as agora,
       dateadd(DAY,3,dateadd(HOUR,3,current_timestamp)) as depois

agora                   depois
----------------------- -----------------------
2005-04-01 06:27:41.367 2005-04-04 09:27:41.367
(1 row(s) affected)

Oracle 10g:

SQL> ALTER SESSION SET TIME_ZONE = local;
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
SQL> ALTER SESSION SET NLS_TIMESTAMP_FORMAT  = 'YYYY-MM-DD HH24:MI:SS.FF';
SQL> ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT  = 'YYYY-MM-DD HH24:MI:SS.FF TZH:TZM';

SQL> SELECT cast('2004-07-16' AS date) + 30
  2  FROM sys.dual;

CAST('2004-07-16'AS
-------------------
2004-08-15 00:00:00

SQL> SELECT cast('2004-07-16' AS date) + INTERVAL '30' DAY
  2  FROM sys.dual;

CAST('2004-07-16'AS
-------------------
2004-08-15 00:00:00

SQL> SELECT cast('2004-07-16 15:00:00' AS timestamp) + 30
  2  FROM sys.dual;

CAST('2004-07-1615:
-------------------
2004-08-15 15:00:00

SQL> SELECT cast('2004-07-16 15:00:00' AS timestamp) + INTERVAL '30' DAY
  2  FROM sys.dual;

CAST('2004-07-1615:00:00'ASTIMESTAMP)+INTERVAL'30'DAY
-----------------------------------------------------
2004-08-15 15:00:00.000000000

SQL> SELECT current_timestamp AS agora, current_timestamp + 3 + 3/24 AS depois
  2  FROM sys.dual;

AGORA                                DEPOIS
------------------------------------ ------------------------------------
2005-04-01 18:04:58.702000 -03:00    2005-04-04 21:04:58

SQL> SELECT current_timestamp AS agora,
  2  current_timestamp + interval '3' day + interval '3' hour AS depois
  3  FROM sys.dual;

AGORA                                DEPOIS
------------------------------------ ------------------------------------
2005-04-01 18:04:59.253000 -03:00    2005-04-04 21:04:59.253000000 -03:00

DB2 8.1:

DB2SQL92> SELECT cast('2004-07-16' AS date) + 30 days
DB2SQL92> FROM sysibm.sysdummy1;

1
------------
15/08/2004

DB2SQL92> SELECT cast('2004-07-16 15:00:00' AS timestamp) + 30 days
DB2SQL92> FROM sysibm.sysdummy1;

1
----------------------------
2004-08-15-15.00.00.000000

DB2SQL92> SELECT current_timestamp, current_timestamp + 3 days + 3 hours
DB2SQL92> FROM sysibm.sysdummy1;

1                           2
--------------------------------------------------------
2005-04-01-07.34.41.953274  2005-04-04-10.34.41.953274

Notas

[1]

60 se estiverem implementados no sistema operacional os segundos intercalados (leap seconds).

[2]

Em certas ocasiões, o UTC é ajustado pela omissão de um segundo ou a inserção do "segundo intercalado" para manter sincronismo com o tempo sideral. Isto implica que às vezes, mas muito raramente, um determinado minuto contém exatamente 59, 61 ou 62 segundos. Se a implementação do SQL suporta os segundos intercalados, e as conseqüências deste suporte para aritmética de data e intervalo, é definido pela implementação. (ISO-ANSI Working Draft) Foundation (SQL/Foundation), August 2003, ISO/IEC JTC 1/SC 32, 25-jul-2003, ISO/IEC 9075-2:2003 (E) (N. do T.)

[3]

O Brasil está a oeste da UTC (ocidente). O horário de Brasília normal corresponde ao GMT-3, e durante o horário de verão corresponde ao GMT-2. (N. do T.)

[4]

A função CURRENT_TIMESTAMP é definida no padrão SQL possuindo o formato <current timestamp value function> ::= CURRENT_TIMESTAMP [ <left paren> <timestamp precision> <right paren> ] (Second Informal Review Draft) ISO/IEC 9075:1992, Database Language SQL- July 30, 1992. (N. do T.)

[5]

Exemplo escrito pelo tradutor, não fazendo parte do manual original.

SourceForge.net Logo