CodeGym /Cursos /C# SELF /Tipos principais para trabalhar com tempo

Tipos principais para trabalhar com tempo

C# SELF
Nível 15, Lição 0
Disponível

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
DateTime.MinValue
= 0001-01-01 00:00:00
Data máxima
DateTime.MaxValue
= 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?

  1. Momento atual
    DateTimeOffset now = DateTimeOffset.Now; // Hora local + offset
    DateTimeOffset utc = DateTimeOffset.UtcNow; // UTC (offset 0)
    
  2. 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));
    
  3. 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
DateTime
Só importa a data, fuso não faz diferença (geralmente)
Hora do login
DateTimeOffset
Precisa saber o momento exato e o offset
Validade do produto
DateTime
Data de expiração, fuso não importa
Hora do evento no log
DateTimeOffset
Melhor sempre guardar com offset
2
Tarefa
C# SELF, nível 15, lição 0
Bloqueado
Exibindo a data e hora atual em vários formatos
Exibindo a data e hora atual em vários formatos
2
Tarefa
C# SELF, nível 15, lição 0
Bloqueado
Adição e subtração de tempo
Adição e subtração de tempo
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION