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.

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 TIMESTAMP aceitos são entradas válidas para datas, mas 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 o horário UTC juntamente com um deslocamento de fuso horário associado. Quando um fuso horário não é fornecido, é usado 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 em um deslocamento numérico 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 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 -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 de quatro dígitos [1].

YY

Ano de dois dígitos [1], 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 [1] (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 de dois dígitos [1] (01 a 31).

DY

Dia da semana abreviado.

HH24

Dois dígitos [1] para hora (00 a 23). Você não deve especificar AM / PM.

HH12

Dois dígitos [1] para hora (01 a 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 [1] para minuto (00 a 59).

SS

Dois dígitos [1] para segundo (00 a 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 [1] de dois dígitos, 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.

[1] O número de dígitos descreve a saída produzida ao serializar valores em texto. Ao analisar texto, o Snowflake aceita até o número especificado de dígitos. Por exemplo, o número de um dia pode ter um ou dois dígitos.

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 OR REPLACE TABLE timestamp_demo_table(
  tstmp TIMESTAMP,
  tstmp_tz TIMESTAMP_TZ,
  tstmp_ntz TIMESTAMP_NTZ,
  tstmp_ltz TIMESTAMP_LTZ);
INSERT INTO timestamp_demo_table (tstmp, tstmp_tz, tstmp_ntz, tstmp_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 tstmp, tstmp_tz, tstmp_ntz, tstmp_ltz
  FROM timestamp_demo_table;
Copy
+-------------------------------+-------------------------------+-------------------------------+-------------------------------+
| TSTMP                         | TSTMP_TZ                      | TSTMP_NTZ                     | TSTMP_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 da data ou hora não for especificada, o intervalo representa 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

A seguir, um exemplo de saída. A saída é diferente quando o carimbo de data/hora atual é diferente.

+-------------------------------+
| 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 dias a e subtrair dias de valores DATE, na forma de { + | - } integer, em que integer especifica o número de dias a serem adicionados ou subtraídos.

Nota

Os valores TIME e TIMESTAMP ainda não oferecem suporte à 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