Tipos de dados de data e hora

O Snowflake oferece suporte a tipos de dados para gerenciar datas, horas e carimbos de data/hora (data e hora combinados). O Snowflake também oferece suporte a formatos para constantes de cadeia de caracteres usadas na manipulação de datas, horas e carimbos de data/hora.

Neste tópico:

Tipos de dados

O Snowflake oferece suporte aos seguintes tipos de dados de data e hora:

Nota

Para dados de DATE e TIMESTAMP, o Snowflake recomenda usar anos entre 1582 e 9999. O Snowflake oferece suporte a alguns anos fora deste intervalo, mas anos anteriores a 1582 devem ser evitados devido a limitações no calendário gregoriano.

DATE

O Snowflake oferece suporte a apenas um tipo de dados de DATE para armazenamento de datas (sem elementos de hora).

DATE aceita datas nas formas mais comuns (YYYY-MM-DD, DD-MON-YYYY e assim por diante).

Além disso, todos os valores de TIMESTAMP aceitos são entradas válidas para datas; entretanto, as informações de TIME são truncadas.

DATETIME

DATETIME é um alias para TIMESTAMP_NTZ.

TIME

O Snowflake oferece suporte a apenas um tipo de dados de TIME para armazenamento de hora no formato de HH:MI:SS.

TIME oferece suporte a um parâmetro de precisão opcional para segundos fracionários (por exemplo, TIME(3)). A precisão do tempo pode variar de 0 (segundos) a 9 (nanossegundos). A precisão padrão é 9.

Todos os valores de TIME devem estar entre 00:00:00 e 23:59:59.999999999. TIME armazena internamente a hora do “relógio de parede”, e todas as operações com valores de TIME são realizadas sem levar em consideração o fuso horário.

TIMESTAMP_LTZ , TIMESTAMP_NTZ , TIMESTAMP_TZ

O Snowflake oferece suporte a três variações de carimbo de data/hora.

TIMESTAMP_LTZ:

TIMESTAMP_LTZ armazena internamente a hora UTC com uma precisão especificada. Entretanto, todas as operações são realizadas no fuso horário da sessão atual, controlado pelo parâmetro de sessão TIMEZONE.

Aliases para TIMESTAMP_LTZ:

  • TIMESTAMPLTZ

  • TIMESTAMP WITH LOCAL TIME ZONE

TIMESTAMP_NTZ:

TIMESTAMP_NTZ armazena internamente a hora do “relógio de parede” com uma precisão especificada. Todas as operações são realizadas sem considerar o fuso horário.

Se o formato de saída contiver um fuso horário, o indicador de UTC (Z) é exibido.

TIMESTAMP_NTZ é o padrão para TIMESTAMP.

Aliases para TIMESTAMP_NTZ:

  • TIMESTAMPNTZ

  • TIMESTAMP WITHOUT TIME ZONE

  • DATETIME

TIMESTAMP_TZ:

TIMESTAMP_TZ armazena internamente a hora UTC junto com um deslocamento de fuso horário associado. Quando não é fornecido um fuso horário, é utilizado o deslocamento de fuso horário da sessão. Todas as operações são realizadas com o deslocamento de fuso horário específico para cada registro.

Aliases para TIMESTAMP_TZ:

  • TIMESTAMPTZ

  • TIMESTAMP WITH TIME ZONE

Os valores de TIMESTAMP_TZ são comparados com base em suas horas em UTC. Por exemplo, a seguinte comparação entre diferentes horas em diferentes fusos horários retorna TRUE porque os dois valores têm horas equivalentes em UTC.

SELECT '2024-01-01 00:00:00 +0000'::TIMESTAMP_TZ = '2024-01-01 01:00:00 +0100'::TIMESTAMP_TZ;
Copy

Atenção

Atualmente, TIMESTAMP_TZ armazena apenas o deslocamento de um determinado fuso horário, não o fuso horário real, no momento da criação para um determinado valor. Isto é especialmente importante para o horário de verão, que não é utilizado pelo UTC.

Por exemplo, com o parâmetro TIMEZONE definido como "America/Los_Angeles", a conversão de um valor para TIMESTAMP_TZ em janeiro de um determinado ano armazena o deslocamento de fuso horário de -0800. Se seis meses depois forem adicionados ao valor, o deslocamento -0800 será mantido, mesmo que em julho o deslocamento para Los Angeles seja -0700. Isto porque, depois que o valor é criado, a informação do fuso horário real ("America/Los_Angeles") não está mais disponível. A seguinte amostra de código ilustra esse comportamento:

SELECT '2024-01-01 12:00:00'::TIMESTAMP_TZ;
Copy
+-------------------------------------+
| '2024-01-01 12:00:00'::TIMESTAMP_TZ |
|-------------------------------------|
| 2024-01-01 12:00:00.000 -0800       |
+-------------------------------------+
SELECT DATEADD(MONTH, 6, '2024-01-01 12:00:00'::TIMESTAMP_TZ);
Copy
+--------------------------------------------------------+
| DATEADD(MONTH, 6, '2024-01-01 12:00:00'::TIMESTAMP_TZ) |
|--------------------------------------------------------|
| 2024-07-01 12:00:00.000 -0800                          |
+--------------------------------------------------------+

TIMESTAMP

TIMESTAMP no Snowflake é um alias especificado pelo usuário associado a uma das variações de TIMESTAMP_*. Em todas as operações em que TIMESTAMP é usado, a variação associada de TIMESTAMP_* é automaticamente usada. O tipo de dados de TIMESTAMP nunca é armazenado em tabelas.

A variação de TIMESTAMP_* associada ao TIMESTAMP é especificada pelo parâmetro de sessão TIMESTAMP_TYPE_MAPPING. O padrão é TIMESTAMP_NTZ.

Todas as variações de carimbo de data/hora, bem como o alias TIMESTAMP, oferecem suporte a um parâmetro de precisão opcional para segundos fracionários (por exemplo, TIMESTAMP(3)). A precisão do carimbo de data/hora pode variar de 0 (segundos) a 9 (nanossegundos). A precisão padrão é 9.

Exemplos de carimbo de data/hora

Esses exemplos criam uma tabela usando diferentes carimbos de data/hora.

Primeiro, crie uma tabela com uma coluna TIMESTAMP (mapeada para TIMESTAMP_NTZ):

ALTER SESSION SET TIMESTAMP_TYPE_MAPPING = TIMESTAMP_NTZ;

CREATE OR REPLACE TABLE ts_test(ts TIMESTAMP);

DESC TABLE ts_test;
Copy
+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name | type             | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| TS   | TIMESTAMP_NTZ(9) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+

Em seguida, use explicitamente uma das variações TIMESTAMP (TIMESTAMP_LTZ):

CREATE OR REPLACE TABLE ts_test(ts TIMESTAMP_LTZ);

DESC TABLE ts_test;
Copy
+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name | type             | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| TS   | TIMESTAMP_LTZ(9) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+

Usar TIMESTAMP_LTZ com fusos horários diferentes:

CREATE OR REPLACE TABLE ts_test(ts TIMESTAMP_LTZ);

ALTER SESSION SET TIMEZONE = 'America/Los_Angeles';

INSERT INTO ts_test VALUES('2024-01-01 16:00:00');
INSERT INTO ts_test VALUES('2024-01-02 16:00:00 +00:00');
Copy

Esta consulta mostra que o horário para 2 de janeiro é 08:00 em Los Angeles (que é 16:00 em UTC):

SELECT ts, hour(ts) FROM ts_test;
Copy
+-------------------------------+----------+
| TS                            | HOUR(TS) |
|-------------------------------+----------|
| 2024-01-01 16:00:00.000 -0800 |       16 |
| 2024-01-02 08:00:00.000 -0800 |        8 |
+-------------------------------+----------+

Em seguida, observe que os horários mudam com um fuso horário diferente:

ALTER SESSION SET TIMEZONE = 'America/New_York';

SELECT ts, HOUR(ts) FROM ts_test;
Copy
+-------------------------------+----------+
| TS                            | HOUR(TS) |
|-------------------------------+----------|
| 2024-01-01 19:00:00.000 -0500 |       19 |
| 2024-01-02 11:00:00.000 -0500 |       11 |
+-------------------------------+----------+

Crie uma tabela e use TIMESTAMP_NTZ:

CREATE OR REPLACE TABLE ts_test(ts TIMESTAMP_NTZ);

ALTER SESSION SET TIMEZONE = 'America/Los_Angeles';

INSERT INTO ts_test VALUES('2024-01-01 16:00:00');
INSERT INTO ts_test VALUES('2024-01-02 16:00:00 +00:00');
Copy

Observe que ambos os horários de fusos horários diferentes são convertidos para a mesma hora local:

SELECT ts, HOUR(ts) FROM ts_test;
Copy
+-------------------------+----------+
| TS                      | HOUR(TS) |
|-------------------------+----------|
| 2024-01-01 16:00:00.000 |       16 |
| 2024-01-02 16:00:00.000 |       16 |
+-------------------------+----------+

Em seguida, observe que alterar o fuso horário da sessão não afeta os resultados:

ALTER SESSION SET TIMEZONE = 'America/New_York';

SELECT ts, HOUR(ts) FROM ts_test;
Copy
+-------------------------+----------+
| TS                      | HOUR(TS) |
|-------------------------+----------|
| 2024-01-01 16:00:00.000 |       16 |
| 2024-01-02 16:00:00.000 |       16 |
+-------------------------+----------+

Crie uma tabela e use TIMESTAMP_TZ:

CREATE OR REPLACE TABLE ts_test(ts TIMESTAMP_TZ);

ALTER SESSION SET TIMEZONE = 'America/Los_Angeles';

INSERT INTO ts_test VALUES('2024-01-01 16:00:00');
INSERT INTO ts_test VALUES('2024-01-02 16:00:00 +00:00');
Copy

Observe que o registro de 1º de janeiro herdou o fuso horário da sessão e “America/Los_Angeles” foi convertido para um deslocamento de fuso horário:

SELECT ts, HOUR(ts) FROM ts_test;
Copy
+-------------------------------+----------+
| TS                            | HOUR(TS) |
|-------------------------------+----------|
| 2024-01-01 16:00:00.000 -0800 |       16 |
| 2024-01-02 16:00:00.000 +0000 |       16 |
+-------------------------------+----------+

Em seguida, observe que alterar o fuso horário da sessão não influencia nos resultados:

ALTER SESSION SET TIMEZONE = 'America/New_York';

SELECT ts, HOUR(ts) FROM ts_test;
Copy
+-------------------------------+----------+
| TS                            | HOUR(TS) |
|-------------------------------+----------|
| 2024-01-01 16:00:00.000 -0800 |       16 |
| 2024-01-02 16:00:00.000 +0000 |       16 |
+-------------------------------+----------+

Calendário com suporte

O Snowflake usa o calendário gregoriano para todas as datas e carimbos de data/hora. O calendário gregoriano começa no ano 1582, mas reconhece os anos anteriores, o que é importante observar porque o Snowflake não ajusta datas anteriores a 1582 (ou faz cálculos envolvendo datas anteriores a 1582) para corresponder ao calendário juliano. O elemento de formato UUUU oferece suporte a anos negativos.

Formatos de data e hora

Todos esses tipos de dados aceitam a maioria dos formatos não ambíguos de data, hora ou data e hora. Consulte Formatos com suporte para detecção AUTO para ver os formatos que o Snowflake reconhece quando configurado para detectar o formato automaticamente.

Você também pode especificar o formato de data e hora manualmente. Ao especificar o formato, você pode usar os elementos que não diferenciam maiúsculas e minúsculas listados na tabela a seguir:

Elemento de formato

Descrição

YYYY

Ano com quatro dígitos.

YY

Ano de dois dígitos, controlado pelo parâmetro de sessão TWO_DIGIT_CENTURY_START. Por exemplo, quando definido como 1980, os valores de 79 e 80 são analisados como 2079 e 1980 respectivamente.

MM

Mês de dois dígitos (01 = janeiro e assim por diante).

MON

Nome do mês completo ou abreviado.

MMMM

Nome completo do mês.

DD

Dia do mês com dois dígitos (01 até 31).

DY

Dia da semana abreviado.

HH24

Dois dígitos para hora (00 até 23). Você não deve especificar AM / PM.

HH12

Dois dígitos para hora (01 até 12). Você pode especificar AM / PM.

AM , PM

Antes do meio-dia (AM) / depois do meio-dia (PM). Use isso somente com HH12 (não com HH24).

MI

Dois dígitos para minuto (00 até 59).

SS

Dois dígitos para o segundo (00 até 59).

FF[0-9]

Segundos fracionários com precisão de 0 (segundos) para 9 (nanossegundos), por exemplo FF, FF0, FF3, FF9. Especificando que FF é equivalente a FF9 (nanossegundos).

TZH:TZM , TZHTZM , TZH

Hora e minuto do fuso horário, ajustados em relação ao UTC. Pode ser prefixado por + / - para sinalizar.

UUUU

Ano de quatro dígitos no formato ISO, que são negativos para anos BCE.

Nota

  • Quando se utiliza um formato somente de data, presume-se que a hora associada seja a meia-noite desse dia.

  • Qualquer elemento no formato entre aspas duplas ou elementos diferentes dos elementos acima é analisado/formatado sem ser interpretado.

  • Para obter mais detalhes sobre intervalos válidos, número de dígitos e práticas recomendadas, consulte Informações adicionais sobre o uso de formatos de data, hora e carimbo de data/hora.

Exemplos de uso de formatos de data e hora

O exemplo a seguir usa FF para indicar que a saída tem 9 dígitos no campo de segundos fracionários:

CREATE TABLE timestamp_demo_table(
  t TIMESTAMP,
  t_tz TIMESTAMP_TZ,
  t_ntz TIMESTAMP_NTZ,
  t_ltz TIMESTAMP_LTZ);
INSERT INTO timestamp_demo_table (t, t_tz, t_ntz, t_ltz) VALUES (
  '2024-03-12 01:02:03.123456789',
  '2024-03-12 01:02:03.123456789',
  '2024-03-12 01:02:03.123456789',
  '2024-03-12 01:02:03.123456789');
Copy
ALTER SESSION SET TIMESTAMP_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
ALTER SESSION SET TIMESTAMP_TZ_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
ALTER SESSION SET TIMESTAMP_NTZ_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
ALTER SESSION SET TIMESTAMP_LTZ_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
Copy
SELECT t, t_tz, t_ntz, t_ltz
  FROM timestamp_demo_table;
Copy
+-------------------------------+-------------------------------+-------------------------------+-------------------------------+
| T                             | T_TZ                          | T_NTZ                         | T_LTZ                         |
|-------------------------------+-------------------------------+-------------------------------+-------------------------------|
| 2024-03-12 01:02:03.123456789 | 2024-03-12 01:02:03.123456789 | 2024-03-12 01:02:03.123456789 | 2024-03-12 01:02:03.123456789 |
+-------------------------------+-------------------------------+-------------------------------+-------------------------------+

Constantes de data e hora

Constantes (também conhecidas como literais) são valores de dados fixos. O Snowflake oferece suporte ao uso de constantes de cadeias de caracteres para especificar valores fixos de data, hora ou carimbo de data/hora. As constantes de cadeias de caracteres devem estar sempre posicionadas entre caracteres delimitadores. O Snowflake oferece suporte ao uso de aspas simples para delimitar as constantes de cadeias de caracteres.

Por exemplo:

DATE '2024-08-14'
TIME '10:03:56'
TIMESTAMP '2024-08-15 10:59:43'
Copy

A cadeia de caracteres é interpretada como um valor DATE, TIME ou TIMESTAMP com base no formato de entrada para o tipo de dados, conforme definido pelos seguintes parâmetros:

DATE:

DATE_INPUT_FORMAT

TIME:

TIME_INPUT_FORMAT

TIMESTAMP:

TIMESTAMP_INPUT_FORMAT

Por exemplo, para inserir uma data específica em uma coluna em uma tabela:

CREATE TABLE t1 (d1 DATE);

INSERT INTO t1 (d1) VALUES (DATE '2024-08-15');
Copy

Constantes de intervalo

É possível usar constantes de intervalo para adicionar ou subtrair um período de tempo para ou de uma data, horário ou carimbo de data/hora. As constantes de intervalo são implementadas usando a palavra-chave INTERVAL, que tem a seguinte sintaxe:

{ + | - } INTERVAL '<integer> [ <date_time_part> ] [ , <integer> [ <date_time_part> ] ... ]'
Copy

Como em todas as constantes de cadeias de caracteres, o Snowflake exige aspas simples para delimitar as constantes de intervalo.

A palavra-chave INTERVAL permite mais um número inteiro e, opcionalmente, uma ou mais partes de data ou hora. Por exemplo:

  • INTERVAL '1 year' representa um ano.

  • INTERVAL '4 years, 5 months, 3 hours' representa quatro anos, cinco meses e três horas.

Se uma parte de data ou hora não for especificado, o intervalo representará segundos (por exemplo, INTERVAL '2' é o mesmo que INTERVAL '2 seconds'). Note que isto é diferente da unidade de tempo padrão para realizar a aritmética de datas. Para obter mais detalhes, consulte Aritmética simples para datas.

Para obter a lista de partes de data e hora compatíveis, consulte Partes de data e hora compatíveis com intervalos.

Nota

  • A ordem dos incrementos de intervalo é importante. Os incrementos são adicionados ou subtraídos na ordem listada. Por exemplo:

    • INTERVAL '1 year, 1 day' primeiro adiciona ou subtrai um ano e depois um dia.

    • INTERVAL '1 day, 1 year' primeiro adiciona ou subtrai um dia e depois um ano.

    Diferenças de ordenação podem afetar cálculos influenciados por eventos do calendário, como anos bissextos:

    SELECT TO_DATE ('2019-02-28') + INTERVAL '1 day, 1 year';
    
    Copy
    +---------------------------------------------------+
    | TO_DATE ('2019-02-28') + INTERVAL '1 DAY, 1 YEAR' |
    |---------------------------------------------------|
    | 2020-03-01                                        |
    +---------------------------------------------------+
    
    SELECT TO_DATE ('2019-02-28') + INTERVAL '1 year, 1 day';
    
    Copy
    +---------------------------------------------------+
    | TO_DATE ('2019-02-28') + INTERVAL '1 YEAR, 1 DAY' |
    |---------------------------------------------------|
    | 2020-02-29                                        |
    +---------------------------------------------------+
    
  • INTERVAL não é um tipo de dados (ou seja, não é possível definir uma coluna de tabela como sendo do tipo de dados INTERVAL). Os intervalos só podem ser usados em aritmética de data, hora e carimbo de data/hora.

  • Você não pode usar um intervalo com uma variável SQL. Por exemplo, a consulta a seguir retorna um erro:

    SET v1 = '1 year';
    
    SELECT TO_DATE('2023-04-15') + INTERVAL $v1;
    
    Copy

Partes de data e hora com suporte para intervalos

A palavra-chave INTERVAL permite as seguintes partes de data e hora como argumentos (sem diferenciação de maiúsculas e minúsculas):

Parte de data ou hora

Abreviações/variações

year

y , yy , yyy , yyyy , yr , years , yrs

quarter

q , qtr , qtrs , quarters

month

mm , mon , mons , months

week

w , wk , weekofyear , woy , wy , weeks

day

d , dd , days, dayofmonth

hour

h , hh , hr , hours , hrs

minute

m , mi , min , minutes , mins

second

s , sec , seconds , secs

millisecond

ms , msec , milliseconds

microsecond

us , usec , microseconds

nanosecond

ns , nsec , nanosec , nsecond , nanoseconds , nanosecs , nseconds

Exemplos de intervalos

Adicionar um intervalo de um ano a uma data específica:

SELECT TO_DATE('2023-04-15') + INTERVAL '1 year';
Copy
+-------------------------------------------+
| TO_DATE('2023-04-15') + INTERVAL '1 YEAR' |
|-------------------------------------------|
| 2024-04-15                                |
+-------------------------------------------+

Adicione um intervalo de 3 horas e 18 minutos a um horário específico:

SELECT TO_TIME('04:15:29') + INTERVAL '3 hours, 18 minutes';
Copy
+------------------------------------------------------+
| TO_TIME('04:15:29') + INTERVAL '3 HOURS, 18 MINUTES' |
|------------------------------------------------------|
| 07:33:29                                             |
+------------------------------------------------------+

Adicionar um intervalo complexo à saída da função CURRENT_TIMESTAMP:

SELECT CURRENT_TIMESTAMP + INTERVAL
    '1 year, 3 quarters, 4 months, 5 weeks, 6 days, 7 minutes, 8 seconds,
    1000 milliseconds, 4000000 microseconds, 5000000001 nanoseconds'
  AS complex_interval1;
Copy
+-------------------------------+
| COMPLEX_INTERVAL1             |
|-------------------------------|
| 2026-11-07 18:07:19.875000001 |
+-------------------------------+

Adicionar um intervalo complexo com notação abreviada de parte de data/hora a uma data específica:

SELECT TO_DATE('2025-01-17') + INTERVAL
    '1 y, 3 q, 4 mm, 5 w, 6 d, 7 h, 9 m, 8 s,
    1000 ms, 445343232 us, 898498273498 ns'
  AS complex_interval2;
Copy
+-------------------------------+
| COMPLEX_INTERVAL2             |
|-------------------------------|
| 2027-03-30 07:31:32.841505498 |
+-------------------------------+

Consulte uma tabela de informações de funcionários e retorne os nomes dos funcionários contratados nos últimos dois anos e três meses:

SELECT name, hire_date
  FROM employees
  WHERE hire_date > CURRENT_DATE - INTERVAL '2 y, 3 month';
Copy

Filtre uma coluna TIMESTAMP nomeada ts de uma tabela nomeada t1 e adicione quatro segundos a cada valor retornado:

SELECT ts + INTERVAL '4 seconds'
  FROM t1
  WHERE ts > TO_TIMESTAMP('2024-04-05 01:02:03');
Copy

Aritmética simples para datas

Além de usar constantes de intervalo para adicionar e subtrair datas, horas e carimbos de data/hora, você também pode adicionar e subtrair dias a e de valores DATE, no formato { + | - }, no formato integer, onde integer especifica o número de dias a serem adicionados/subtraídos.

Nota

Os valores de TIME e TIMESTAMP ainda não têm suporte para aritmética simples.

Exemplos de aritmética de datas

Adicione um dia a uma data específica:

SELECT TO_DATE('2024-04-15') + 1;
Copy
+---------------------------+
| TO_DATE('2024-04-15') + 1 |
|---------------------------|
| 2024-04-16                |
+---------------------------+

Subtraia quatro dias de uma data específica:

SELECT TO_DATE('2024-04-15') - 4;
Copy
+---------------------------+
| TO_DATE('2024-04-15') - 4 |
|---------------------------|
| 2024-04-11                |
+---------------------------+

Consultar uma tabela chamada employees e retornar os nomes das pessoas que deixaram a empresa, mas foram empregadas por mais de 365 dias:

SELECT name
  FROM employees
  WHERE end_date > start_date + 365;
Copy