C# Datas e Horas
Quando vence o boleto? Quantos dias faltam para o Natal? Quanto tempo durou o filme? Que horas são em Lisboa? Datas aparecem em quase todo programa, e fazer essas contas "na mão" é difícil: os meses têm tamanhos diferentes, há anos bissextos e fusos horários. O C# tem tipos prontos para tudo isso. Nesta aula você vai usar o DateTime (data e hora), o TimeSpan (um intervalo de tempo), o DateOnly e o TimeOnly (só a data, só a hora), e vai calcular a multa da biblioteca da Ana.
- Pegar a data e a hora de agora (
DateTime.Now,Today,UtcNow) e criar uma data qualquer. - Ler as partes:
Year,Month,Day,Hour,DayOfWeek. - Formatar em português:
"d","D","dd/MM/yyyy","HH:mm","dddd". - Somar e subtrair:
AddDays,AddMonths, e oTimeSpanque sai de uma subtração. - Usar
DateOnlyeTimeOnlyquando só a data ou só a hora importa. - Transformar texto em data:
Parse,ParseExacteTryParse. - Fusos horários com
TimeZoneInfoeDateTimeOffset.
Os programas rodam com dotnet run no computador da Ana, que está em português do Brasil e no fuso de São Paulo (UTC−3). As datas e os nomes de dias e meses aparecem como no Brasil. A aula Cultura mostra como isso muda em outros países.
A ideia: o calendário e o cronômetro
Pense em duas coisas da sua casa. O calendário com relógio marca um momento: "sábado, 17 de outubro de 2026, às 14h30". Isso é um DateTime. O cronômetro mede uma duração: "2 horas e 15 minutos", sem dizer quando começou. Isso é um TimeSpan.
As contas entre os dois são as do dia a dia: um momento mais uma duração dá outro momento ("o filme começa às 19h e dura 2h15, então acaba às 21h15"). Um momento menos outro dá uma duração ("do dia 17 de outubro ao Natal são 69 dias").
| Tipo | Guarda | Exemplo |
|---|---|---|
DateTime | Data e hora | 17/10/2026 14:30:00 |
DateOnly .NET 6 | Só a data | Um aniversário: 08/03/1997 |
TimeOnly .NET 6 | Só a hora do dia | A loja abre às 08:00 |
TimeSpan | Uma duração | 02:15:00 (2 horas e 15 minutos) |
DateTimeOffset | Data, hora e o fuso | 17/10/2026 14:30:00 −03:00 |
Todos são structs do namespace System, que já vem incluído.
1. Agora: DateTime.Now
DateTime agora = DateTime.Now; Console.WriteLine(agora); Console.WriteLine(DateTime.Today); Console.WriteLine(DateTime.UtcNow);
$ date sáb 17 out 2026 12:57:03 -03 $ dotnet run agora.cs 17/10/2026 12:57:07 17/10/2026 00:00:00 17/10/2026 15:57:07
- DateTime.Now
- "Agora": a data e a hora do relógio do computador, no fuso dele. Cada vez que você roda, sai um valor diferente.
- DateTime.Today
- "Hoje": a data de hoje, com a hora zerada (meia-noite).
- DateTime.UtcNow
- Agora em UTC, o horário de referência do mundo (o de Greenwich, em Londres, sem horário de verão). São Paulo está 3 horas atrás: 12h57 aqui são 15h57 em UTC.
- Console.WriteLine(agora)
- Mostra no formato do Brasil, dia/mês/ano e hora com 24 horas, porque o computador está em pt-BR.
Um programa que usa DateTime.Now dá um resultado diferente a cada dia, o que dificulta conferir se ele está certo. Nos exemplos e nas missões desta aula, a data de "hoje" é fixa (new DateTime(2026, 10, 17)). Nos seus programas, troque pela DateTime.Today quando estiver tudo funcionando.
2. Uma data qualquer, e as partes dela
DateTime prova = new DateTime(2026, 10, 17, 14, 30, 0); Console.WriteLine(prova); Console.WriteLine(prova.Year); Console.WriteLine(prova.Month); Console.WriteLine(prova.Day); Console.WriteLine(prova.Hour); Console.WriteLine(prova.DayOfWeek); Console.WriteLine(prova.DayOfYear);
$ dotnet run data.cs 17/10/2026 14:30:00 2026 10 17 14 Saturday 290
- new DateTime(2026, 10, 17, 14, 30, 0)
- Ano, mês, dia, hora, minuto e segundo, nessa ordem (do maior para o menor, nunca dia/mês/ano). Sem a hora,
new DateTime(2026, 10, 17)é meia-noite. - Year, Month, Day, Hour, Minute, Second
- As partes, como números
int. - DayOfWeek
- O dia da semana, que é um enum, e por isso aparece com o nome em inglês:
Saturday(sábado). Serve para comparar:prova.DayOfWeek == DayOfWeek.Saturday. Para mostrar em português, use o formato"dddd"(seção 3). - DayOfYear
- Que dia do ano é: 17 de outubro é o 290º dia de 2026.
3. Formatar: ToString com códigos
O ToString de uma data aceita um texto com o formato, igual aos números da aula Formatar Números. Existem formatos prontos de uma letra e formatos "montados" com códigos:
DateTime prova = new DateTime(2026, 10, 17, 14, 30, 0);
Console.WriteLine(prova.ToString("d"));
Console.WriteLine(prova.ToString("D"));
Console.WriteLine(prova.ToString("t"));
Console.WriteLine(prova.ToString("F"));
Console.WriteLine(prova.ToString("dd/MM/yyyy HH:mm"));
Console.WriteLine(prova.ToString("dddd"));
Console.WriteLine(prova.ToString("MMMM"));
Console.WriteLine(prova.ToString("ddd, dd 'de' MMM"));
Console.WriteLine(prova.ToString("yyyy-MM-dd"));
Console.WriteLine($"Prova: {prova:dd/MM}");
$ dotnet run formatos.cs 17/10/2026 sábado, 17 de outubro de 2026 14:30 sábado, 17 de outubro de 2026 14:30:00 17/10/2026 14:30 sábado outubro sáb., 17 de out. 2026-10-17 Prova: 17/10
| Código | Significa | Exemplo |
|---|---|---|
d (sozinho) | Data curta | 17/10/2026 |
D (sozinho) | Data longa | sábado, 17 de outubro de 2026 |
t / T (sozinhos) | Hora curta / com segundos | 14:30 / 14:30:00 |
F (sozinho) | Data longa e hora | sábado, 17 de outubro de 2026 14:30:00 |
dd / ddd / dddd | Dia com 2 dígitos / dia da semana curto / longo | 17 / sáb. / sábado |
MM / MMM / MMMM | Mês com 2 dígitos / nome curto / longo | 10 / out. / outubro |
yyyy | Ano com 4 dígitos | 2026 |
HH / hh | Hora de 0 a 23 / de 1 a 12 | 14 / 02 |
mm / ss | Minutos / segundos | 30 / 00 |
'texto' | Texto escrito como está | 'de' → de |
Atenção às maiúsculas: MM é mês e mm é minuto (veja "Quando dá errado"). O formato yyyy-MM-dd é o padrão internacional ISO 8601: ele não depende do país, e os arquivos ordenados pelo nome ficam em ordem de data. Use-o em nomes de arquivos e em dados que outros programas vão ler.
4. Somar e subtrair: Add e TimeSpan
DateTime hoje = new DateTime(2026, 10, 17);
Console.WriteLine(hoje.AddDays(14).ToString("d"));
Console.WriteLine(hoje.AddDays(-1).ToString("d"));
Console.WriteLine(hoje.AddMonths(3).ToString("d"));
Console.WriteLine(new DateTime(2026, 1, 31).AddMonths(1).ToString("d"));
Console.WriteLine(hoje.AddHours(36));
DateTime natal = new DateTime(2026, 12, 25);
TimeSpan falta = natal - hoje;
Console.WriteLine(falta);
Console.WriteLine(falta.Days);
Console.WriteLine(falta.TotalHours);
Console.WriteLine(natal > hoje);
$ dotnet run contas.cs 31/10/2026 16/10/2026 17/01/2027 28/02/2026 18/10/2026 12:00:00 69.00:00:00 69 1656 True
- hoje.AddDays(14)
- "Somar dias": devolve uma data nova, 14 dias depois. A
hojenão muda: umDateTimenunca muda depois de criado. Por isso é preciso guardar o resultado (DateTime prazo = hoje.AddDays(14);). - AddDays(-1)
- Com número negativo, volta no tempo.
- AddMonths(3)
- Três meses depois, virando o ano se precisar. Também existem
AddYears,AddHours,AddMinutes,AddSeconds. - 31/01 + 1 mês = 28/02
- Fevereiro de 2026 não tem dia 31, então o
AddMonthsusa o último dia do mês. Fazer essa conta somando 30 dias daria errado. - natal - hoje
- Uma data menos outra dá um
TimeSpan. Ele aparece comodias.horas:minutos:segundos:69.00:00:00são 69 dias e zero horas. - falta.Days e falta.TotalHours
Daysé a parte dos dias (int).TotalHoursé a duração inteira convertida em horas (double): 69 × 24 = 1656. ExistemHours/TotalHours,Minutes/TotalMinutese assim por diante.- natal > hoje
- Datas se comparam com
<,>e==, como números: a mais tarde é a "maior".
Missão: a frase saiu Faltam 69.00:00:00 para o Natal. Use a propriedade Days do TimeSpan para a saída ficar Faltam 69 dias para o Natal.
DateTime hoje = new DateTime(2026, 10, 17);
DateTime natal = new DateTime(2026, 12, 25);
TimeSpan falta = natal - hoje;
Console.WriteLine($"Faltam {falta} para o Natal");
DateTime hoje = new DateTime(2026, 10, 17);
DateTime natal = new DateTime(2026, 12, 25);
TimeSpan falta = natal - hoje;
Console.WriteLine($"Faltam {falta.Days} dias para o Natal");
Durações: TimeSpan
Um TimeSpan também pode ser criado direto, para somar a uma data ou a outro TimeSpan:
TimeSpan filme = new TimeSpan(2, 15, 0);
TimeSpan aula = TimeSpan.FromMinutes(90);
Console.WriteLine(filme);
Console.WriteLine(filme.TotalMinutes);
Console.WriteLine(aula);
Console.WriteLine(filme + aula);
DateTime inicio = new DateTime(2026, 10, 17, 19, 0, 0);
Console.WriteLine($"O filme acaba às {(inicio + filme):t}");
Console.WriteLine($"{filme.Hours}h{filme.Minutes:00}");
$ dotnet run filme.cs 02:15:00 135 01:30:00 03:45:00 O filme acaba às 21:15 2h15
- new TimeSpan(2, 15, 0)
- Horas, minutos e segundos. Com quatro números, o primeiro são os dias:
new TimeSpan(1, 2, 0, 0)é 1 dia e 2 horas. - TimeSpan.FromMinutes(90)
- Uma duração a partir de uma quantidade:
FromDays,FromHours,FromMinutes,FromSeconds. 90 minutos viram01:30:00. - filme + aula
- Durações se somam: 2h15 + 1h30 = 3h45.
- inicio + filme
- Momento mais duração dá um momento: 19h00 + 2h15 = 21h15. Os parênteses em
{(inicio + filme):t}são necessários para a conta ser feita antes do formato. - {filme.Minutes:00}
- O formato
00garante dois dígitos:5sairia05.
5. Só a data, só a hora: DateOnly e TimeOnly
Um aniversário não tem hora. O horário de abertura da loja não tem data. Guardar esses valores num DateTime funciona, mas leva junto uma parte que não significa nada (a "meia-noite" do aniversário). Desde o .NET 6, existem tipos só para isso:
DateOnly nascimento = new DateOnly(1997, 3, 8);
DateOnly hoje = new DateOnly(2026, 10, 17);
Console.WriteLine(nascimento);
Console.WriteLine(nascimento.ToString("D"));
int idade = hoje.Year - nascimento.Year;
if (hoje < nascimento.AddYears(idade))
{
idade--;
}
Console.WriteLine($"Idade: {idade}");
Console.WriteLine($"Dias de vida: {hoje.DayNumber - nascimento.DayNumber}");
TimeOnly abre = new TimeOnly(8, 0);
TimeOnly fecha = new TimeOnly(18, 30);
TimeOnly agora = new TimeOnly(19, 15);
Console.WriteLine($"Aberta das {abre} às {fecha}: {fecha - abre} por dia");
Console.WriteLine($"Aberta às {agora}? {agora.IsBetween(abre, fecha)}");
$ dotnet run aniversario.cs 08/03/1997 sábado, 8 de março de 1997 Idade: 29 Dias de vida: 10815 Aberta das 08:00 às 18:30: 10:30:00 por dia Aberta às 19:15? False
- new DateOnly(1997, 3, 8)
- Ano, mês e dia. Mostra só a data, sem
00:00:00. - a conta da idade
- Primeiro, a diferença dos anos (2026 − 1997 = 29). Depois, se o aniversário deste ano ainda não chegou (
hoje < nascimento.AddYears(idade)), tira um. A Ana fez aniversário em março, então tem 29. - DayNumber
- O número do dia contado desde 1º de janeiro do ano 1. A diferença entre dois
DayNumberé a quantidade de dias entre as datas. (ODateOnlynão tem o operador-; veja "Quando dá errado".) - new TimeOnly(8, 0)
- Hora e minuto. A diferença entre dois
TimeOnlyé umTimeSpan. - agora.IsBetween(abre, fecha)
- "Está entre?":
Truese a hora está no intervalo. 19h15 está fora.
Para converter: DateOnly.FromDateTime(umDateTime) pega só a data, e umDateOnly.ToDateTime(umTimeOnly) junta uma data e uma hora num DateTime.
6. Texto → data: Parse, ParseExact e TryParse
Datas digitadas pelo usuário ou lidas de um arquivo chegam como texto. Como os números da aula Parse e TryParse, elas precisam ser convertidas:
using System.Globalization;
DateTime d1 = DateTime.Parse("17/10/2026");
Console.WriteLine(d1.ToString("D"));
DateTime d2 = DateTime.Parse("2026-10-17 14:30");
Console.WriteLine(d2);
DateTime d3 = DateTime.ParseExact("10/17/2026", "MM/dd/yyyy", CultureInfo.InvariantCulture);
Console.WriteLine(d3.ToString("d"));
if (DateOnly.TryParseExact("08/03/1997", "dd/MM/yyyy", out DateOnly nasc))
{
Console.WriteLine($"Nasceu no dia da semana: {nasc:dddd}");
}
if (!DateOnly.TryParse("31/02/2026", out DateOnly ruim))
{
Console.WriteLine("Data inválida");
}
$ dotnet run parse.cs sábado, 17 de outubro de 2026 17/10/2026 14:30:00 17/10/2026 Nasceu no dia da semana: sábado Data inválida
- DateTime.Parse("17/10/2026")
- Entende o texto no formato do país do computador: em pt-BR, dia/mês/ano. O formato ISO (
2026-10-17) é aceito em qualquer país. - DateTime.ParseExact(texto, "MM/dd/yyyy", CultureInfo.InvariantCulture)
- "Converter exatamente": você diz o formato, com os códigos da seção 3. Aqui, uma data no estilo dos Estados Unidos, mês primeiro. O
CultureInfo.InvariantCulture(aula Cultura) diz que o texto não depende do país. - DateOnly.TryParseExact(texto, "dd/MM/yyyy", out DateOnly nasc)
- A versão segura: devolve
truee põe a data emnascse deu certo, oufalsesem exceção. Use sempre oTryParsecom texto digitado pelo usuário. - "31/02/2026"
- Fevereiro não tem dia 31: o
TryParsedevolvefalse.
7. Fusos horários
Quando é 14h30 em São Paulo, é 18h30 em Lisboa e 13h30 em Manaus. O TimeZoneInfo ("informação de fuso") conhece os fusos do mundo e converte entre eles. No Linux, cada fuso tem um nome do tipo Continente/Cidade:
DateTime aqui = new DateTime(2026, 10, 17, 14, 30, 0, DateTimeKind.Local);
Console.WriteLine(TimeZoneInfo.Local.Id);
Console.WriteLine(TimeZoneInfo.Local.GetUtcOffset(aqui));
Console.WriteLine($"UTC: {aqui.ToUniversalTime()}");
TimeZoneInfo lisboa = TimeZoneInfo.FindSystemTimeZoneById("Europe/Lisbon");
TimeZoneInfo manaus = TimeZoneInfo.FindSystemTimeZoneById("America/Manaus");
Console.WriteLine($"Lisboa: {TimeZoneInfo.ConvertTime(aqui, lisboa)}");
Console.WriteLine($"Manaus: {TimeZoneInfo.ConvertTime(aqui, manaus)}");
DateTimeOffset reuniao = new DateTimeOffset(2026, 10, 17, 14, 30, 0, TimeSpan.FromHours(-3));
Console.WriteLine(reuniao);
Console.WriteLine(reuniao.ToUniversalTime());
$ dotnet run fuso.cs America/Sao_Paulo -03:00:00 UTC: 17/10/2026 17:30:00 Lisboa: 17/10/2026 18:30:00 Manaus: 17/10/2026 13:30:00 17/10/2026 14:30:00 -03:00 17/10/2026 17:30:00 +00:00
- DateTimeKind.Local
- O último argumento diz de que fuso é a data:
Local(o do computador),UtcouUnspecified(não se sabe, o padrão donew DateTime). A propriedadeKindguarda isso. - TimeZoneInfo.Local
- O fuso do computador:
America/Sao_Paulo, 3 horas atrás do UTC (-03:00:00). - ToUniversalTime()
- A mesma hora, em UTC.
- TimeZoneInfo.FindSystemTimeZoneById("Europe/Lisbon")
- Procura um fuso pelo nome.
ConvertTimemostra a mesma hora no relógio de lá, já com o horário de verão de cada lugar. - DateTimeOffset
- Um momento com a diferença para o UTC junto (
-03:00). Não há dúvida sobre de que fuso ele é. Prefira-o para guardar quando algo aconteceu (uma compra, um login), principalmente num sistema usado em vários lugares.
Qual tipo usar
| Você quer guardar… | Use |
|---|---|
| Um aniversário, um feriado, um vencimento | DateOnly |
| Um horário que se repete (abre às 8h) | TimeOnly |
| Uma duração (2h15, 14 dias) | TimeSpan |
| Um compromisso no seu fuso | DateTime |
| Quando algo aconteceu, num sistema com usuários em vários fusos | DateTimeOffset ou DateTime.UtcNow |
| Data num arquivo ou para outro programa | Texto no formato ISO: ToString("yyyy-MM-dd") ou ToString("o") |
Quando dá errado
FormatException: a data no formato de outro país
DateTime d = DateTime.Parse("10/17/2026");
Console.WriteLine(d);
$ dotnet run erro1.cs Unhandled exception. System.FormatException: String '10/17/2026' was not recognized as a valid DateTime. at System.DateTimeParse.Parse(ReadOnlySpan`1 s, DateTimeFormatInfo dtfi, DateTimeStyles styles) at Program.<Main>$(String[] args) in /home/ana/cs/erro1.cs:line 1
O que aconteceu: "O texto não foi reconhecido como uma data válida". Em pt-BR, o Parse lê dia/mês/ano, e não existe mês 17. Pior ainda é "05/10/2026", que dá certo nos dois países, mas é 5 de outubro aqui e 10 de maio nos Estados Unidos: sem erro, com a data errada.
Como resolver: se você sabe o formato do texto, diga qual é: DateTime.ParseExact("10/17/2026", "MM/dd/yyyy", CultureInfo.InvariantCulture). Com texto digitado, TryParse ou TryParseExact. Nos seus arquivos, grave no formato ISO, yyyy-MM-dd, que não tem ambiguidade.
ArgumentOutOfRangeException: 30 de fevereiro
DateTime d = new DateTime(2026, 2, 30);
$ dotnet run erro2.cs Unhandled exception. System.ArgumentOutOfRangeException: Year, Month, and Day parameters describe an un-representable DateTime. at System.DateTime..ctor(Int32 year, Int32 month, Int32 day) at Program.<Main>$(String[] args) in /home/ana/cs/erro2.cs:line 1
O que aconteceu: "Ano, mês e dia descrevem uma data que não pode existir". O mesmo acontece com o mês 13, a hora 24 ou, muito comum, com a ordem trocada: new DateTime(17, 10, 2026) tenta o ano 17, mês 10, dia 2026.
Como resolver: ano, mês, dia, sempre nessa ordem. Para saber quantos dias um mês tem, DateTime.DaysInMonth(2026, 2) devolve 28. Para "o mesmo dia no mês que vem", use AddMonths(1), que já ajusta o fim do mês.
mm no lugar de MM
DateTime d = new DateTime(2026, 10, 17, 14, 5, 0);
Console.WriteLine(d.ToString("dd/mm/yyyy"));
Console.WriteLine(d.ToString("hh:mm"));
Console.WriteLine(d.ToString("HH:mm"));
$ dotnet run mm.cs 17/05/2026 02:05 14:05
O que aconteceu: nenhum erro, só o resultado errado. Em dd/mm/yyyy, o mm são os minutos (5), e não o mês. E em hh:mm, o hh é a hora de 12 horas: 14h05 virou 02:05, sem dizer se é da manhã ou da tarde.
Como resolver: MM maiúsculo para o mês, HH maiúsculo para a hora de 0 a 23: dd/MM/yyyy HH:mm.
CS0019 e CS0029: contas que o tipo não faz
$ cat menos.cs DateOnly a = new DateOnly(2026, 10, 17); DateOnly b = new DateOnly(2026, 12, 25); Console.WriteLine(b - a); $ dotnet run menos.cs /home/ana/cs/menos.cs(3,19): error CS0019: O operador "-" não pode ser aplicado a operandos dos tipos "DateOnly" e "DateOnly" Ocorreu uma falha no build. Corrija os erros de build e execute novamente. $ cat dias.cs DateTime a = new DateTime(2026, 10, 17); DateTime b = new DateTime(2026, 12, 25); int dias = b - a; $ dotnet run dias.cs /home/ana/cs/dias.cs(3,12): error CS0029: Não é possível converter implicitamente tipo "System.TimeSpan" em "int" Ocorreu uma falha no build. Corrija os erros de build e execute novamente.
O que aconteceu: o DateOnly não sabe subtrair outro DateOnly (em inglês, Operator '-' cannot be applied to operands of type 'DateOnly' and 'DateOnly'). E a subtração de dois DateTime dá um TimeSpan, que não é um int.
Como resolver: com DateOnly, b.DayNumber - a.DayNumber. Com DateTime, int dias = (b - a).Days;.
Saturday em vez de sábado
O que aconteceu: Console.WriteLine(d.DayOfWeek) mostra o nome do valor do enum, que é sempre em inglês, em qualquer país.
Como resolver: para mostrar, d.ToString("dddd"), que segue a língua do computador (sábado). Para decidir, compare com o enum: if (d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday) é "fim de semana".
Referência rápida
| Código | O que faz |
|---|---|
DateTime.Now / DateTime.Today / DateTime.UtcNow | Agora / hoje à meia-noite / agora em UTC |
new DateTime(ano, mês, dia, h, min, s) | Uma data e hora |
d.Year, Month, Day, Hour, Minute, DayOfWeek, DayOfYear | As partes |
d.ToString("dd/MM/yyyy HH:mm"), "d", "D", "dddd" | Formatar |
d.AddDays(n), AddMonths, AddYears, AddHours, AddMinutes | Uma data nova, depois (ou antes, com negativo) |
b - a | A diferença, como TimeSpan |
t.Days, t.Hours / t.TotalDays, t.TotalHours | Uma parte / a duração inteira na unidade |
new TimeSpan(h, min, s), TimeSpan.FromMinutes(n) | Uma duração |
new DateOnly(a, m, d), new TimeOnly(h, min) | Só a data / só a hora |
DateOnly.FromDateTime(d), x.DayNumber | Converter / dias entre datas |
DateTime.Parse(t), ParseExact(t, formato, cultura), TryParse(t, out d) | Texto → data |
DateTime.DaysInMonth(ano, mês) | Quantos dias o mês tem |
TimeZoneInfo.FindSystemTimeZoneById("Europe/Lisbon"), TimeZoneInfo.ConvertTime(d, fuso) | Fusos |
new DateTimeOffset(…, TimeSpan.FromHours(-3)) | Data e hora com o fuso junto |
Exercícios
1. Daqui a uma semana
Complete para calcular a data 7 dias depois de hoje:
2. O formato brasileiro
Complete o formato para a data aparecer como 05/03/2026 (dia, mês e ano com 4 dígitos):
3. Só os dias
A variável falta é um TimeSpan. Complete para pegar a quantidade de dias como int:
4. O que new DateTime(2026, 1, 31).AddMonths(1) devolve?
5. Qual tipo é o melhor para guardar o aniversário de alguém?
6. Um programa mostra d.ToString("dd/mm/yyyy") e a data sai com um "mês" estranho, como 17/42/2026. Por quê?
Missão final: a multa da biblioteca
Missão: a biblioteca da escola empresta livros por 14 dias e cobra R$ 1,50 por dia de atraso. A Ana pegou um livro em 17/10/2026 e devolveu em 05/11/2026. Complete o programa:
- calcule o
prazocomemprestimo.AddDays(14)e mostreDevolver até:com o formatodddd, dd/MM/yyyy; - calcule o
atrasoem dias comDayNumber(devolução menos prazo); - se houver atraso, mostre
Atraso: N diaseMulta: R$com o valor emF2; se não,Devolvido no prazo.
A saída deve ser:
Devolver até: sábado, 31/10/2026 Atraso: 5 dias Multa: R$ 7,50
DateOnly emprestimo = new DateOnly(2026, 10, 17);
DateOnly devolucao = new DateOnly(2026, 11, 5);
decimal multaPorDia = 1.50m;
Console.WriteLine($"Emprestado em: {emprestimo:dddd, dd/MM/yyyy}");
// 1. o prazo (14 dias depois do empréstimo)
// 2. o atraso, em dias
// 3. a multa
DateOnly emprestimo = new DateOnly(2026, 10, 17);
DateOnly devolucao = new DateOnly(2026, 11, 5);
decimal multaPorDia = 1.50m;
Console.WriteLine($"Emprestado em: {emprestimo:dddd, dd/MM/yyyy}");
DateOnly prazo = emprestimo.AddDays(14);
Console.WriteLine($"Devolver até: {prazo:dddd, dd/MM/yyyy}");
int atraso = devolucao.DayNumber - prazo.DayNumber;
if (atraso > 0)
{
Console.WriteLine($"Atraso: {atraso} dias");
Console.WriteLine($"Multa: R$ {atraso * multaPorDia:F2}");
}
else
{
Console.WriteLine("Devolvido no prazo");
}
Depois de cumprir a missão, troque a devolução para new DateOnly(2026, 10, 30) e veja o Devolvido no prazo. Se quiser ir além: a biblioteca não abre aos domingos; se o prazo cair num domingo, passe para segunda (if (prazo.DayOfWeek == DayOfWeek.Sunday)).
Resumo
DateTimeé um momento (data e hora);TimeSpané uma duração. Momento − momento = duração; momento + duração = momento.DateTime.Nowmuda a cada execução: para testar, use datas fixas comnew DateTime(ano, mês, dia).AddDays,AddMonthse companhia devolvem uma data nova e cuidam dos meses de tamanhos diferentes.- Formate com
ToString:dd/MM/yyyy HH:mm(MM = mês, mm = minuto, HH = 24 horas),ddddeMMMMem português,yyyy-MM-ddpara arquivos. DateOnlyeTimeOnlyguardam só a data ou só a hora; dias entreDateOnlycomDayNumber.- Texto → data:
TryParsecom texto do usuário,ParseExactquando você sabe o formato. Fusos:TimeZoneInfoeDateTimeOffset.