1. Conhecendo o tipo DateTime
Data e hora são tipo o tijolinho básico de qualquer lógica de negócio, não dá pra ignorar nem nos projetos mais simples. Direto precisa saber quando o usuário se registrou, quando mandar um e-mail, tratar certinho o horário de voos, fusos — data tá em tudo! Mas, na real, trabalhar com data e hora é uma das paradas mais traiçoeiras da programação. 😅
C# oferece dois tipos que são bem importantes pra lidar com tempo: DateTime e DateTimeOffset. Resumindo — um é pra cenários mais simples, o outro é pra quando tem que lidar com fuso horário e guardar o horário certinho.
O que é DateTime?
O tipo DateTime é uma struct definida no namespace System. Ele serve pra guardar data e hora com precisão de até 100 nanossegundos (1/10 de bilionésimo de segundo).
- É um tipo valor (struct), ou seja, copia por valor.
- Guarda tanto a data quanto a hora.
- Dá pra guardar só a data (2025-05-24) ou data com hora (2025-05-24 15:17:42).
- “Não sabe” nada de fuso horário, a não ser que você diga explicitamente.
2. Criando DateTime
Tem várias formas, bora ver as principais.
1. Data e hora atual
DateTime now = DateTime.Now; // Hora local do computador
DateTime utcNow = DateTime.UtcNow; // Hora de Greenwich (UTC)
- Now — é “como tá no seu PC”, levando em conta o fuso local do Windows.
- UtcNow — “universal”, ou seja, horário coordenado mundial. Muito bom pra guardar em banco de dados ou sistemas que rodam no mundo todo.
2. Construtores
// Ano, mês, dia
var date1 = new DateTime(2025, 5, 24);
// Ano, mês, dia, hora, minuto, segundo
var date2 = new DateTime(2025, 5, 24, 12, 0, 0);
// Ano, mês, dia, hora, minuto, segundo, milissegundo
var date3 = new DateTime(2025, 5, 24, 12, 0, 0, 500);
Os meses não começam do zero! Ou seja, janeiro é 1, dezembro é 12.
3. Parseando de string
Direto a data chega como string! Tipo, o usuário digita a data na mão.
string userInput = "2025-05-24 18:30";
DateTime parsed = DateTime.Parse(userInput); // Pode lançar exceção!
Pra fazer o parse de boa — usa TryParse:
string input = "2025-05-24 18:30";
if (DateTime.TryParse(input, out DateTime result))
{
Console.WriteLine($"Convertido com sucesso: {result}");
}
else
{
Console.WriteLine("Não rolou converter a string pra data.");
}
4. Pegando a data “sem hora”
DateTime today = DateTime.Today; // Dia atual, mas hora = 00:00:00
Extraindo componentes de data e hora
Dá pra pegar tudo rapidinho:
var dt = new DateTime(2025, 5, 24, 15, 17, 42);
int year = dt.Year; // 2025
int month = dt.Month; // 5 (maio)
int day = dt.Day; // 24
int hour = dt.Hour; // 15
int minute = dt.Minute; // 17
int second = dt.Second; // 42
DayOfWeek dow = dt.DayOfWeek; // Sexta-feira
3. Trabalhando com o tipo DateTime
Somando e subtraindo datas
Tempo em programação passa voando, então pra não ficar contando “quanto falta pro deadline”, usa os métodos da classe:
DateTime now = DateTime.Now;
DateTime tomorrow = now.AddDays(1); // Amanhã
DateTime afterFiveHours = now.AddHours(5); // Daqui 5 horas
DateTime inTenMinutes = now.AddMinutes(10); // Daqui 10 minutos
Diferença entre duas datas: TimeSpan
A diferença entre duas datas é um valor separado, tipo TimeSpan:
DateTime deadline = new DateTime(2026, 6, 1);
DateTime now = DateTime.Now;
TimeSpan untilDeadline = deadline - now;
Console.WriteLine($"Dias até o deadline: {untilDeadline.Days}");
Console.WriteLine($"Horas até o deadline: {untilDeadline.TotalHours:N2}");
TimeSpan é a “diferença”, não uma data/hora específica!
Checando se a data é no futuro/passado
if (deadline > now)
Console.WriteLine("O deadline ainda tá pra chegar!");
else
Console.WriteLine("O deadline já passou! Bora entregar logo!");
4. Como as datas são guardadas por baixo dos panos
Pra facilitar soma e subtração de datas, os devs decidiram guardar tudo como quantidade de segundos desde o começo da nossa era. Os valores do range:
| Propriedade | Valor |
|---|---|
| Data mínima | = 0001-01-01 00:00:00 |
| Data máxima | = 9999-12-31 23:59:59.9999999 |
| Unidade de medida | 1 tick = 100 nanossegundos |
DateTime não guarda só a quantidade de segundos, mas sim a quantidade de “ticks” (ticks) desde uma data especial — 1 de janeiro do ano 0001 (sim, dev não liga pra dinossauro, o calendário deles é rígido). Um tick = 100 nanossegundos.
5. Tipo DateTimeOffset
Às vezes o DateTime não dá conta. Imagina: a empresa tá em dois países, cada um num fuso, e todas as reuniões são “no meu horário”. E aí?
O horário salvo como DateTime geralmente é “abstrato”: só um monte de número e tick, até você dizer em que zona foi. Tipo, se você recebe "2025-05-24 15:00", não dá pra saber — é horário de Nairóbi? Bagdá? Berlim? (e se for horário de verão então, segura!).
Por isso, pra situações onde precisa marcar o momento exato no tempo, e não só “data do calendário”, surgiu o segundo tipo — DateTimeOffset. Criando um DateTimeOffset com offset (tipo Nairóbi +3 no UTC):
var localTime = new DateTimeOffset(2025, 5, 24, 15, 0, 0, TimeSpan.FromHours(3));
Usa DateTimeOffset se:
- Precisa saber o momento exato (tipo eventos de log, marcados pelo horário do servidor).
- O app lida com usuários em vários fusos.
- Precisa guardar/enviar hora com zona (tipo transações, eventos, agendas).
6. Como criar DateTimeOffset?
- Momento atual
DateTimeOffset now = DateTimeOffset.Now; // Hora local + offset DateTimeOffset utc = DateTimeOffset.UtcNow; // UTC (offset 0) - Criação explícita
// Ano, mês, dia, hora, minuto, segundo, offset (tipo +2 horas) DateTimeOffset custom = new DateTimeOffset(2025, 5, 24, 20, 0, 0, TimeSpan.FromHours(2)); - Convertendo de DateTime
DateTime dt = DateTime.Now; DateTimeOffset dto = new DateTimeOffset(dt); // O offset local é pego automaticamente
Extraindo componentes
DateTimeOffset dto = DateTimeOffset.Now;
var datePart = dto.Date; // Só a data
var timePart = dto.TimeOfDay; // Só a hora
var offset = dto.Offset; // Offset em relação ao UTC, tipo 03:00:00
Convertendo entre zonas de tempo
Magia dos offsets:
// Pega a data em UTC
var now = DateTimeOffset.Now;
var utc = now.ToUniversalTime();
Console.WriteLine(utc); // Hora de Greenwich
// Converte pra outro fuso
var berlinTime = utc.ToOffset(TimeSpan.FromHours(2));
Console.WriteLine(berlinTime); // Pra Berlim (CET +2)
7. Quando usar DateTime e quando DateTimeOffset?
Filosofia da escolha
Quando é algo simples e local — tipo aniversário, data de publicação de artigo ou deadline de pesquisa até 15:00, normalmente DateTime já resolve. Nesses casos, o horário absoluto não importa, só interessa que rolou naquele dia e hora, sem ligar pra fuso.
Agora, se precisa registrar o momento exato levando em conta o fuso, tipo em logs, transações ou sistemas distribuídos — melhor usar DateTimeOffset. Assim não rola confusão quando o horário passa de um sistema pra outro, principalmente se cada um tá num fuso diferente.
| Cenário | Tipo | Por quê |
|---|---|---|
| Aniversário | |
Só importa a data, fuso não faz diferença (geralmente) |
| Hora do login | |
Precisa saber o momento exato e o offset |
| Validade do produto | |
Data de expiração, fuso não importa |
| Hora do evento no log | |
Melhor sempre guardar com offset |
GO TO FULL VERSION