CodeGym /Cursos /C# SELF /Cálculos e classes auxiliares para datas e horários

Cálculos e classes auxiliares para datas e horários

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

1. Tarefas principais quando mexendo com data e hora

Trabalhar com datas e horários geralmente dá aquele leve (ou nem tão leve) desespero até pra dev experiente. Tu vai ter que comparar datas, calcular intervalos, somar ou subtrair dias/meses/anos, calcular idade, descobrir o dia da semana e muito mais.

Tudo isso é tarefa clássica pra trackers de tarefas e calendários, controle de assinaturas, cálculos financeiros, relatórios estatísticos e, claro, pra perguntas de entrevista (tipo "calcule quantos dias úteis entre duas datas").

No C# e .NET tem classes e métodos prontos pra isso. E o melhor: quase tudo é feito via API orientada a objetos, super segura e fácil de entender.

2. Estrutura TimeSpan — medindo intervalos de tempo

Tudo começa com a struct TimeSpan. É tipo um "pedaço" de tempo: por exemplo, 5 dias, 3 horas, 7 minutos e 21 segundos.

Como criar um TimeSpan?

Dá pra "subtrair" duas datas, ou criar direto:

// Diferença entre duas datas sempre é TimeSpan!
DateTime start = new DateTime(2025, 5, 1, 7, 0, 0);
DateTime end = new DateTime(2025, 5, 2, 11, 30, 0);

TimeSpan duration = end - start; // Magia total!
Console.WriteLine(duration); // 1.04:30:00 (1 dia, 4 horas, 30 minutos)

Dá pra criar um TimeSpan passando os parâmetros no construtor:

TimeSpan span = new TimeSpan(2, 14, 18, 0); // 2 dias, 14 horas, 18 minutos, 0 segundos
Console.WriteLine(span); // 2.14:18:00

Outra forma é usando métodos estáticos, que geralmente ficam mais legíveis:

TimeSpan fiveMinutes = TimeSpan.FromMinutes(5);
TimeSpan twoHours = TimeSpan.FromHours(2);
TimeSpan oneWeek = TimeSpan.FromDays(7);

Quais propriedades tem o TimeSpan?

Propriedade Descrição
Days
Número inteiro de dias
Hours
Parte das horas
Minutes
Parte dos minutos
Seconds
Parte dos segundos
TotalDays
Tempo em dias (com fração)
TotalHours
Tempo em horas (com fração)
TotalMinutes
Tempo em minutos (com fração)
TotalSeconds
Tempo em segundos (com fração)
Console.WriteLine($"Dias: {duration.Days}, Total de horas: {duration.TotalHours}");

Como somar/subtrair TimeSpan de uma data?

DateTime now = DateTime.Now;
DateTime future = now.Add(duration); // Somou duration ao now
DateTime past = now.Subtract(TimeSpan.FromDays(10)); // Menos 10 dias

Console.WriteLine(future);
Console.WriteLine(past);

3. Calculadora de datas: calculando diferença entre datas

Uma skill que tu vai usar sempre. Tipo, alguém quer saber quanto falta pro recesso, outro quer saber quando acaba o período grátis.

DateTime today = DateTime.Today;
DateTime vacation = new DateTime(2025, 8, 1);
TimeSpan untilVacation = vacation - today;

Console.WriteLine($"Faltam {untilVacation.Days} dias pro recesso!");

Repara: se tu subtrai só "datas" sem hora (usando DateTime.Date ou DateTime.Today), o resultado é sempre número inteiro de dias. Se uma das datas tem hora, aí a diferença é fracionada.


int days = (vacation - today).TotalDays; // Erro de compilação! TotalDays é double

Se tu quer inteiro — usa .Days ou converte pra inteiro com (int)TotalDays.

4. Somando e subtraindo tempo: métodos AddDays, AddMonths, AddHours, ...

C# não te obriga a contar dias de cada mês, ano bissexto e essas tretas. Só usa:

DateTime orderDate = new DateTime(2024, 4, 20);
DateTime deliveryDate = orderDate.AddDays(14); // Daqui 2 semanas

Console.WriteLine($"O produto vai ser entregue em {deliveryDate.ToShortDateString()}");
Método O que soma (ou subtrai se for negativo)
AddDays(double)
Dias (aceita fração, tipo 1,5 dia)
AddMonths(int)
Meses (já calcula o tamanho do mês certinho)
AddYears(int)
Anos (até cuida de ano bissexto)
AddHours(double)
Horas
AddMinutes(double)
Minutos
AddSeconds(double)
Segundos
DateTime birthday = new DateTime(2000, 2, 29);
DateTime nextYear = birthday.AddYears(1); // 2001-02-28 (não é 29, porque 2001 não é bissexto)
Console.WriteLine(nextYear.ToShortDateString()); // 28.02.2001

Não esquece: todos os métodos retornam um novo objeto de data, a data original não muda!

var dt = DateTime.Now;
dt.AddDays(5); // Isso NÃO muda dt!
dt = dt.AddDays(5); // Agora sim mudou

5. Métodos auxiliares pra cálculos

Descobrindo o dia da semana

Na maioria dos casos tu pode usar a propriedade .DayOfWeek:

DateTime examDate = new DateTime(2025, 6, 19);
DayOfWeek day = examDate.DayOfWeek;
Console.WriteLine(day); // Wednesday

Dá pra converter pra número inteiro:

int number = (int)day; // Sunday == 0, Monday == 1, e por aí vai

Checando "hoje", "ontem", "amanhã"

Comparação básica:

DateTime date = new DateTime(2025, 6, 18);

if (date.Date == DateTime.Today)
    Console.WriteLine("Hoje!");
else if (date.Date == DateTime.Today.AddDays(-1))
    Console.WriteLine("Ontem!");
else if (date.Date == DateTime.Today.AddDays(1))
    Console.WriteLine("Amanhã!");

Calculando idade

Uma das tarefas mais comuns — calcular a idade da pessoa do jeito certo. Só subtrair os anos nem sempre dá certo:

public static int CalculateAge(DateTime birthDate, DateTime currentDate)
{
    int age = currentDate.Year - birthDate.Year;
    
    // Se o aniversário ainda não chegou esse ano
    if (currentDate.Month < birthDate.Month || 
        (currentDate.Month == birthDate.Month && currentDate.Day < birthDate.Day))
    {
        age--;
    }
    
    return age;
}

// Usando
DateTime birth = new DateTime(1990, 8, 15);
DateTime today = DateTime.Today;
int age = CalculateAge(birth, today);
Console.WriteLine($"Idade: {age} anos");

Trabalhando com dias úteis

Muitas vezes tu precisa calcular quantos dias úteis tem entre duas datas, pulando finais de semana:

public static int CountWorkingDays(DateTime startDate, DateTime endDate)
{
    int workingDays = 0;
    DateTime current = startDate;
    
    while (current <= endDate)
    {
        if (current.DayOfWeek != DayOfWeek.Saturday && 
            current.DayOfWeek != DayOfWeek.Sunday)
        {
            workingDays++;
        }
        current = current.AddDays(1);
    }
    
    return workingDays;
}

6. Como as classes principais se conectam

graph TD
    A(DateTime) --subtração--> B(TimeSpan)
    A2(DateTime) --AddDays, AddMonths--> A
    A --ToLocalTime/ToUniversalTime--> C(DateTimeOffset)
    D(DateOnly) --ToDateTime--> A
    E(TimeOnly) --ToTimeSpan--> B
    A --DayOfWeek, Day, Month, Year--> F(Propriedades numéricas)
    B(TimeSpan) --TotalDays, TotalHours, ...--> G(Propriedades de duração)

7. Guia rápido: o que fazer se...

Tarefa O que usar Exemplo
Descobrir diferença entre datas
TimeSpan duration = d2 - d1
(d2 - d1).Days
Somar 2 semanas a uma data
date.AddDays(14)
date.AddDays(14)
Calcular idade Fórmula com
.Year
e checando mês/dia
Vê a seção acima
Pegar/definir só a data
DateOnly
DateOnly.FromDateTime(DateTime.Now)
Pegar/definir só a hora
TimeOnly
TimeOnly.FromDateTime(DateTime.Now)
Comparar datas Operadores
<
,
>
,
==
,
.CompareTo()
if (d1 < d2) ...
Converter pra outro fuso horário
DateTimeOffset + ToOffset
dto.ToOffset(TimeSpan.FromHours(3))
Descobrir o número da semana no ano
Calendar.GetWeekOfYear()
vê a documentação
Descobrir o dia da semana
date.DayOfWeek
Contar dias úteis Loop checando
DayOfWeek
Vê a seção acima
1
Pesquisa/teste
Trabalhando com datas, nível 15, lição 4
Indisponível
Trabalhando com datas
Trabalhando com datas, horários e fusos horários
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION