Entenda os tipos de data/hora do SQL Server e aprenda a trabalhar com datas no dia a dia: extração de partes, diferenças, filtros de período e melhores práticas.
Dominar os tipos de data/hora (DATE, TIME, DATETIME, DATETIME2, SMALLDATETIME) e as funções mais usadas na prática: YEAR, MONTH, DAY, GETDATE, DATEPART, DATEDIFF.
| Tipo | Tamanho | Precisão | Intervalo | Quando usar |
|---|---|---|---|---|
| DATE | 3 bytes | Dia | 0001–9999 | Datas sem hora (aniversário, vencimento) |
| TIME | 3–5 bytes | Até 100ns | 00:00:00–23:59:59.9999999 | Horários (abre/fecha) |
| DATETIME | 8 bytes | ~3ms | 1753–9999 | Legado; prefira DATETIME2 |
| DATETIME2 | 6–8 bytes | Até 100ns | 0001–9999 | Timestamp moderno recomendado |
| SMALLDATETIME | 4 bytes | 1 min | 1900–2079 | Quando minuto é suficiente |
DATEO que é / Para que serve: Armazena apenas a data (sem hora).
Sintaxe: col DATE
Como funciona: Guarda ano, mês e dia. Ideal para datas puras.
Implicações & boas práticas: • Usa menos espaço. • Combine com TIME se precisar guardar também o horário.
CREATE TABLE Ferias (ColaboradorID INT, Inicio DATE, Fim DATE);
INSERT INTO Ferias VALUES (1,'2025-09-01','2025-09-10');
SELECT * FROM Ferias;
TIMEO que é / Para que serve: Armazena apenas o horário do dia.
Sintaxe: col TIME[(s)] -- s = 0 a 7 casas fracionárias
Como funciona: Quanto maior a precisão, mais bytes são usados (3–5 bytes).
Implicações & boas práticas: • Bom para agendas. • Não guarda fuso/offset.
CREATE TABLE Expediente (DiaSemana TINYINT, Abre TIME(0), Fecha TIME(0));
INSERT INTO Expediente VALUES (1,'08:00','17:00');
SELECT * FROM Expediente;
DATETIME (legado)O que é / Para que serve: Data e hora com precisão ~3ms.
Sintaxe: col DATETIME
Como funciona: Amplamente usado historicamente, mas com limitações de precisão.
Implicações & boas práticas: • Prefira DATETIME2 em projetos novos. • GETDATE() retorna DATETIME.
CREATE TABLE LogAntigo (CriadoEm DATETIME DEFAULT(GETDATE()));
INSERT INTO LogAntigo DEFAULT VALUES;
SELECT CriadoEm FROM LogAntigo;
DATETIME2O que é / Para que serve: Data e hora moderna com precisão configurável.
Sintaxe: col DATETIME2[(s)] -- s = 0..7
Como funciona: Mais amplo e preciso que DATETIME; SYSDATETIME() retorna DATETIME2(7).
Implicações & boas práticas: • Recomendado para timestamps. • Pode usar GETUTCDATE/SYSUTCDATETIME para UTC.
CREATE TABLE LogNovo (CriadoEm DATETIME2(3) DEFAULT(SYSDATETIME()));
INSERT INTO LogNovo DEFAULT VALUES;
SELECT CriadoEm FROM LogNovo;
SMALLDATETIMEO que é / Para que serve: Data e hora com precisão de minuto.
Sintaxe: col SMALLDATETIME
Como funciona: Arredonda para o minuto mais próximo (sem segundos fracionários).
Implicações & boas práticas: • Menor armazenamento, mas intervalo até 2079. • Útil quando segundo não é necessário.
CREATE TABLE Eventos (Inicio SMALLDATETIME);
INSERT INTO Eventos VALUES ('2025-09-01 08:15');
SELECT * FROM Eventos;
GETDATE()O que é / Para que serve: Retorna a data/hora atual do servidor (DATETIME).
Sintaxe: GETDATE()
Como funciona: Avaliado no servidor quando a consulta é executada.
Implicações & boas práticas: • Usa fuso do servidor. • Para maior precisão use SYSDATETIME().
SELECT GETDATE() AS Agora;
YEAR / MONTH / DAYO que é / Para que serve: Extrair partes de uma data.
Sintaxe: YEAR(data) | MONTH(data) | DAY(data)
Como funciona: Retornam inteiros correspondentes ao ano, mês e dia.
Implicações & boas práticas: • Em filtros, prefira faixas (>= e <) para usar índices, em vez de aplicar função na coluna.
SELECT YEAR(GETDATE()) AS Ano, MONTH(GETDATE()) AS Mes, DAY(GETDATE()) AS Dia;
DATEPARTO que é / Para que serve: Extrair uma parte específica da data, como day, month, year, weekday etc.
Sintaxe: DATEPART(parte, data) -- parte: year, month, day, hour, minute, second, weekday...
Como funciona: Retorna um inteiro de acordo com a parte pedida.
Implicações & boas práticas: • Útil em relatórios. • Evite em colunas em WHERE (pode quebrar índices).
SELECT DATEPART(weekday, GETDATE()) AS DiaSemana, DATEPART(hour, GETDATE()) AS HoraAtual;
DATEDIFFO que é / Para que serve: Calcular a diferença inteira entre duas datas em uma unidade escolhida.
Sintaxe: DATEDIFF(parte, inicio, fim)
Como funciona: Conta quantas “fronteiras” da unidade foram cruzadas entre início e fim.
Implicações & boas práticas: • Resultado é inteiro (pode “virar” no limite). • Para intervalo completo de um dia, use técnica de faixa aberta (>= e <).
SELECT DATEDIFF(day, '2025-08-01', '2025-08-27') AS Dias;
SELECT DATEDIFF(minute, '2025-08-27 08:00', '2025-08-27 08:59:59.999') AS Minutos;
Evite usar BETWEEN com datas de fim ajustadas manualmente. Prefira a técnica de faixa aberta no fim:
DECLARE @ini DATE = '2025-09-01';
DECLARE @fim DATE = '2025-10-01'; -- dia imediatamente seguinte ao período desejado
SELECT *
FROM Vendas
WHERE CriadoEm >= @ini
AND CriadoEm < @fim; -- inclui todo 30/09, qualquer fração de segundo
DATETIME, DATETIME2 e SMALLDATETIME e costuma preservar o uso de índices.CriadoEm DATETIME2(3) DEFAULT(SYSDATETIME()) e insira 3 linhas em horários diferentes.YEAR, MONTH, DAY.DATEDIFF.