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
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:
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.
O campo dia (do mês) (1 - 31)
SELECT extract(DAY FROM TIMESTAMP '2001-02-16 20:38:40'); Resultado: 16
O campo ano dividido por 10
SELECT extract(DECADE FROM TIMESTAMP '2001-02-16 20:38:40'); Resultado: 200
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
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
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';
O campo hora (0 - 23)
SELECT extract(HOUR FROM TIMESTAMP '2001-02-16 20:38:40'); Resultado: 20
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
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.
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
O campo minutos (0 - 59)
SELECT extract(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); Resultado: 38
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
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
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
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]
O componente hora do deslocamento da zona horária
O componente minuto do deslocamento da zona horária
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
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
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
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.
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.
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)
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
[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. |