9.9. 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.8. É 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. Também, os operadores + e * ocorrem em pares comutativos (por exemplo, pares data + inteiro e inteiro + data); é mostrado apenas um destes pares.

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'
+ 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 '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'
- timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00' interval '1 day 15:00'
* 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, timestamp) interval Subtrai os argumentos, produzindo um resultado "simbólico" que utiliza anos e meses age(timestamp '2001-04-10', timestamp '1957-06-13') 43 years 9 mons 27 days
age(timestamp) interval Subtrai de current_date age(timestamp '1957-06-13') 43 years 8 mons 3 days
current_date date Data de hoje; consulte a Seção 9.9.4    
current_time time with time zone Hora do dia; consulte a Seção 9.9.4    
current_timestamp timestamp with time zone Data e hora; consulte a Seção 9.9.4    
date_part(text, timestamp) double precision Retorna subcampo (equivale ao extract); consulte a Seção 9.9.1 date_part('hour', timestamp '2001-02-16 20:38:40') 20
date_part(text, interval) double precision Retorna subcampo (equivale ao extract); consulte a Seção 9.9.1 date_part('month', interval '2 years 3 months') 3
date_trunc(text, timestamp) timestamp Trunca na precisão especificada; consulte a Seção 9.9.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; consulte a Seção 9.9.1 extract(hour from timestamp '2001-02-16 20:38:40') 20
extract(campo from interval) double precision Retorna subcampo; consulte a Seção 9.9.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; consulte a Seção 9.9.4    
localtimestamp timestamp Data e hora; consulte a Seção 9.9.4    
now() timestamp with time zone Data e hora corrente (equivale ao current_timestamp); consulte a Seção 9.9.4    
timeofday() text Data e hora corrente; consulte a Seção 9.9.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.9.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, time ou interval (As expressões do tipo date são convertidas em timestamp, podendo, portanto serem utilizadas também. 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 século

SELECT extract(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
Resultado: 20
SELECT extract(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 21

O primeiro século começou em 0001-01-01 00:00:00 DC, embora não se soubesse disso naquela época. Esta definição se aplica a todos os países que utilizam o calendário Gregoriano. Não existe o século número 0, vai direto de -1 para 1. Se você não concorda com isto, por favor envie sua reclamação para: Papa, Basílica de São Pedro, Cidade do Vaticano.

As versões do PostgreSQL anteriores a 8.0 não seguiam a numeração dos séculos convencional, retornando simplesmente o campo ano dividido por 100.

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

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

 domingo
---------
 1

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

 sábado
--------
      6

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

 sábado
--------
 7
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

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

 dia
-----
 366
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

Abaixo está mostrado como converter de volta um valor de época para um valor de carimbo do tempo:

SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 982384720 * INTERVAL '1 second';
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 milênio

SELECT extract(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
Resultado: 3

Os anos em 1900 estão no segundo milênio. O terceiro milênio começou em 1 de janeiro de 2001.

As versões do PostgreSQL anteriores a 8.0 não seguiam a numeração dos milênios convencional, retornando simplesmente o campo ano dividido por 1000.

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, consulte a Seção 9.8.

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.9.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
week
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.9.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'). No caso do texto, os nomes disponíveis para zona horária são os mostrados na Tabela B-4 (seria mais útil suportar os nomes mais gerais mostrados na Tabela B-6, mas isto ainda não está implementado).

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.9.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.9.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-9. Utilização de INTERVAL

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

PostgreSQL 8.0.0:

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

 intervalo
-----------
 10 days

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

    interval
-----------------
 4 days 05:12:00

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-10. 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. Consulte também Getting the difference between Dates, DB2 Basics: Fun with Dates and Times e SQL Server 2005 Books Online — DATEDIFF (Transact-SQL)

PostgreSQL 8.0.0:

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

 dias
------
  237

SQL Server 2000:

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

dias
----
237

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 9.1:

db2 => VALUES(days(date('1950-07-16'))- days(date('1949-11-21')));

1
-----------
        237

db2 => VALUES(julian_day(date('1950-07-16'))-julian_day(date('1949-11-21')));

1
-----------
        237

db2 => VALUES(date('1950-07-16') - date('1949-11-21'));

1
----------
      725,  (1)


(1)
7 meses e 25 dias

Exemplo 9-11. 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.

PostgreSQL 8.0.0:

=> SELECT CURRENT_TIMESTAMP,
->       date_part('day',CURRENT_TIMESTAMP) AS d1,
->       extract(DAY FROM CURRENT_TIMESTAMP) AS d2,
->       to_char(CURRENT_TIMESTAMP,'DD') AS d3;

      timestamptz       | d1 | d2 | d3
------------------------+----+----+----
 2007-02-23 05:53:17-03 | 23 | 23 | 23

SQL Server 2000:

SELECT CURRENT_TIMESTAMP AS "Carimbo do Tempo",
       datepart(DAY, CURRENT_TIMESTAMP) AS d1,
       day(CURRENT_TIMESTAMP) AS d2

Carimbo do Tempo                 d1          d2
-------------------------------- ----------- -----------
2007-02-23 05:58:06.513          23          23

Oracle 10g:

SQL> SELECT CURRENT_TIMESTAMP,
 2        to_char(CURRENT_TIMESTAMP,'DD') AS d1,
 3        extract(DAY FROM CURRENT_TIMESTAMP) AS d2
 4  FROM sys.dual;

CURRENT_TIMESTAMP               D1         D2
------------------------------- -- ----------
23/02/07 05:28:04,171343 -03:00 23         23

DB2 9.1:

db2 => VALUES(CURRENT_TIMESTAMP, day(CURRENT_TIMESTAMP));

1                          2
-------------------------- -----------
2007-02-23-05.23.24.840536          23

Exemplo 9-12. 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] Consulte também CURRENT_TIMESTAMP no Oracle, CURRENT_TIMESTAMP no SQL Server e CURRENT_TIMESTAMP no DB2.

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

PostgreSQL 8.0.0:

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

    date    |        agora
------------+---------------------
 2007-02-23 | 23-02-2007 08:07:59

=> SELECT CURRENT_TIME, CURRENT_TIME(0), LOCALTIME, LOCALTIME (0);

      timetz      |   timetz    |     time      |   time
------------------+-------------+---------------+----------
 08:07:59.9060-03 | 08:08:00-03 | 08:07:59.9060 | 08:08:00

=> SELECT CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(0), LOCALTIMESTAMP(0);

        timestamptz         |      timestamptz       |      timestamp
----------------------------+------------------------+---------------------
 2007-02-23 08:07:59.906-03 | 2007-02-23 08:08:00-03 | 2007-02-23 08:08:00

=> SELECT now(), timeofday(), CURRENT_TIMESTAMP AT TIME ZONE 'UTC' AS UTC;

            now             |              timeofday              |           utc
----------------------------+-------------------------------------+-------------------------
 2007-02-23 08:07:59.906-03 | Fri Feb 23 08:09:56.671000 2007 BRT | 2007-02-23 11:07:59.906
=> END;

SQL Server 2000:

SELECT CURRENT_TIMESTAMP AS "CURRENT_TIMESTAMP",
       getdate() AS "getdate()"

CURRENT_TIMESTAMP       getdate()
----------------------- -----------------------
2007-02-23 08:17:49.607 2007-02-23 08:17:49.607

SELECT getutcdate() AS "getutcdate()",
       convert(VARCHAR, CURRENT_TIMESTAMP, 121) AS "convert()"

getutcdate()            convert()
----------------------- -----------------------
2007-02-23 11:21:13.543 2007-02-23 08:21:13.543

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> COLUMN CURRENT_DATE FORMAT A34;
SQL> COLUMN AGORA FORMAT A34;
SQL> COLUMN CURRENT_TIMESTAMP FORMAT A34;
SQL> COLUMN CURRENT_TIMESTAMP(0) FORMAT A34;
SQL> COLUMN LOCALTIMESTAMP FORMAT A34;
SQL> COLUMN LOCALTIMESTAMP(0) FORMAT A34;
SQL> COLUMN UTC FORMAT A34;
SQL> COLUMN SYS_EXTRACT_UTC(CURRENT_TIMESTAMP) FORMAT A34;

SQL> SELECT CURRENT_DATE,
 2        to_char(CURRENT_TIMESTAMP, 'DD-MM-YYYY HH24:MI:SS') AS agora
 3  FROM sys.dual;
CURRENT_DATE                       AGORA
---------------------------------- ----------------------------------
2007-02-23                         23-02-2007 09:04:26

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

CURRENT_TIMESTAMP                  CURRENT_TIMESTAMP(0)
---------------------------------- ----------------------------------
2007-02-23 09:04:26.111336 -03:00  2007-02-23 09:04:26. -03:00

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

LOCALTIMESTAMP                     LOCALTIMESTAMP(0)
---------------------------------- ----------------------------------
2007-02-23 09:04:26.112095         2007-02-23 09:04:26.

SQL> SELECT CURRENT_TIMESTAMP AT TIME ZONE 'UTC' AS UTC,
 2        SYS_EXTRACT_UTC(CURRENT_TIMESTAMP)
 3  FROM sys.dual;
UTC                                SYS_EXTRACT_UTC(CURRENT_TIMESTAMP)
---------------------------------- ----------------------------------
2007-02-23 12:55:17.445796 +00:00  2007-02-23 12:55:17.445796

DB2 9.1:

db2 => VALUES(CURRENT_DATE, to_char(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS'));

1          2
---------- -------------------
23/02/2007 2007-02-23 09:14:27

db2 => VALUES(CURRENT_TIME, CURRENT_TIMESTAMP);

1        2
-------- --------------------------
09:21:00 2007-02-23-09.21.00.765756

-- Remover os microssegundos

db2 => VALUES(CURRENT TIMESTAMP - MICROSECOND (CURRENT TIMESTAMP) MICROSECONDS);

1
--------------------------
2007-02-23-09.22.46.000000

-- Hora UTC

db2 => VALUES(CURRENT TIMESTAMP, CURRENT TIMEZONE, CURRENT TIMESTAMP - CURRENT TIMEZONE);

1                          2        3
-------------------------- -------- --------------------------
2007-02-23-09.37.43.778107  -30000, 2007-02-23-12.37.43.778107

Exemplo 9-13. 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 8.0.0:

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

      timestamp
---------------------
 1999-01-01 12:34:56

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

      timestamp
---------------------
 1999-01-01 12:34:56

SQL Server 2000:

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

timestamp
-----------------------
1999-01-01 12:34:56.000

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

timestamp
-----------------------
1999-01-01 12:34:56.000

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 9.1:

db2 => VALUES(timestamp('1999-01-01','12.34.56'));

1
--------------------------
1999-01-01-12.34.56.000000

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

1
--------------------------
1999-01-01-12.34.56.000000

Exemplo 9-14. 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 8.0.0:

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

    data
------------
 2004-08-15

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

        data
---------------------
 2004-08-15 00:00:00

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

        data
---------------------
 2004-08-15 15:00:00

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

           agora            |           depois
----------------------------+----------------------------
 2007-03-04 08:41:03.796-03 | 2007-03-07 11:41:03.796-03

SQL Server 2000:

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

data
-------------------
2004-08-15 00:00:00

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

data
-----------------------
2004-08-15 15:00:00.000

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

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> COLUMN agora FORMAT A36;
SQL> COLUMN depois FORMAT A36;

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 to_date('2004-07-16')  + numtodsinterval(30, 'day')
 2  FROM sys.dual;

TO_DATE('2004-07-16
-------------------
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
------------------------------------ ------------------------------------
2007-03-04 08:03:42.156136 -03:00    2007-03-07 11:03:42

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

AGORA                                DEPOIS
------------------------------------ ------------------------------------
2007-03-04 08:04:46.168338 -03:00    2007-03-07 11:04:46.168338000 -03:00

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

AGORA                                DEPOIS
------------------------------------ ------------------------------------
2007-03-04 08:05:27.084089 -03:00    2007-03-07 11:05:27.084089000 -03:00

DB2 9.1:

db2 => VALUES(cast('2004-07-16' AS date) + 30 days);

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

db2 => VALUES(cast('2004-07-16 15:00:00' AS timestamp) + 30 days);

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

db2 => VALUES(CURRENT_TIMESTAMP, CURRENT_TIMESTAMP + 3 DAYS + 3 HOURS);

1                          2
-------------------------- --------------------------
2007-02-23-10.12.30.273250 2007-02-26-13.12.30.273250

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 CSS válido!