Lidando com data e hora C#
Uma empresa de estacionamento precisa registrar o dia e hora de entrada e saída dos carros e, atualmente, realiza esse processo manualmente, inserindo no sistema cada informação em um campo separado:
Entrada:
Console.WriteLine("Digite a data e hora da entrada");
String dataEntrada = Console.ReadLine();
Console.WriteLine(dataEntrada);
Saída:
Console.WriteLine("Digite a data e hora da saída");
String dataSaida = Console.ReadLine();
Console.WriteLine(dataSaida);
No final do mês, ao analisar em uma tabela a lista de entradas e saídas tínhamos alguns valores meio estranhos:
Data (entrada - saída)| Hora (entrada - saída)
----------------------------------------------
12102000 1210000 | 12h30 - 11h30
----------------------------------------------
08/03/2019 10/02/2019 | 11:00 - 11:00
----------------------------------------------
01-02-2015 05/08/2019 | 10:00h - 10:30h
----------------------------------------------
00-00-0000 20/02-2006 | 23:00h - 14:30h
----------------------------------------------
31-12-2012 30-12-2012 | 12:00h - 13:00h
----------------------------------------------
2018/02/24 2018/03/07 | 11:00am - 22:00pm
----------------------------------------------
Essa tabela tem algumas datas que estão com os valores formatados sem padronização, além de ter valores que não têm sentido, por exemplo:
- Entrada com data posterior a da saída (ENTRADA: 31-12-2012, SAÍDA:30-12-2012);
- Entrada com valores zerados, como (00-00-000);
- Horário com padrão americano (am e pm), indicação de horas com "h" e sem, etc. americano.
Então, para evitar este tipo de erro, podemos deixar uma formatação já pré-definida, ou seja, podemos criar um padrão para que esses valores sejam recebidos sempre da mesma forma. Assim garantimos que apenas surgirão valores padronizados e essa confusão deixa de existir. Mas como fazemos isto em C#?
Atualmente, o valor recebido de data e hora está contido em uma String. Com isto nós podemos colocar qualquer valor nela seja em texto ou em número, mas a String pode conter erros de formatação e, além disso, do jeito que está implementada agora não contém nenhuma validação.
Utilizar String para fazer a formatação e validação demandaria muito tempo e código, pois teríamos que fazer a formatação muito detalhada, validando cada fragmento de data e hora, como por exemplo funções para validar se está com os valores corretos. Felizmente, no C# temos um tipo específico para fazer essa validação e formatação de data
Formatação de data e hora
No C# temos o DateTime que é uma classe específica para trabalhar com data e hora e também formatar de maneira mais fácil e ainda contém algumas funções para data e hora.
Vamos utilizar a instância direta do DateTime:
DateTime data = new DateTime();
Console.WriteLine(data);
E teremos esse resultado:
01/01/0001 00:00:00
Este não é o resultado que nós gostaríamos. Este valor é retornado quando não passamos nada no construtor, pois é a data padrão que está no definida no DateTime. Então vamos passar os valores para o construtor desta vez e ver como fica. Ele espera os valores de: ano, mês, dia, hora, minuto, segundo.
Então vamos usar como por exemplo a data: 01/05/2019 e a hora 13:52:22. Quando colocarmos os valores no construtor, a variável terá, por padrão, os valores que estão definidos no construtor.
Depois disso criaremos as variáveis de ano, mês e dia para o código ficar mais legível e atribuir elas no construtor do nosso DateTime.
int ano = 2019;
int mes = 05 ;
int dia = 01 ;
DateTime dataEntrada = new DateTime(ano, mes, dia);
Mas como mostramos nosso horário formatado na tela? Usamos o Console.WriteLine para isto.
Console.WriteLine(dataEntrada);
Nosso valor de saída então vai ser:
01/05/2019 00:00:00
Porém com isto a hora está com os valores padrão do construtor, então vamos colocar a hora, minutos e segundos, então vamos fazer o mesmo procedimento atribuindo os valores nas variáveis e colocar os valores no construtor.
int hora = 13;
int minuto = 52;
int segundo = 22;
DateTime dataEntrada = new DateTime(ano,mes,dia,hora,minuto,segundo);
Console.WriteLine(dataEntrada);
Nossa saída vai ser:
01/05/2019 13:52:22
Nossa saída está de acordo com data, hora e formato o nosso sistema operacional ou seja se por exemplo nós rodamos este mesmo código em um compilador online que a data, hora e formato está com formato americano qual vai ser nossa saída?
A nossa saída vai ser em formato americano, pois está pegando de acordo com o que está definido no sistema.
5/1/2019 1:52:22 PM
Para que isto não aconteça vamos definir o locale da queremos a data, como podemos fazer isto? Vamos primeiramente importar duas bibliotecas a Threading que é a de criar um thread (um novo processamento, no nosso caso para a formatação) e o Globalization para definirmos a região que queremos.
Para importar as bibliotecas temos que fazer assim e vamos por no topo do nosso código para que fique mais organizado:
using System.Globalization;
using System.Threading;
Como no compilador online não funciona, vamos testar mudando o nosso horário, que está com o formato brasileiro, para o formato americano, passamos no construtor o formato que queremos, "en-us," e o outro se é necessário usar as configurações de cultura do sistema.
Então vamos colocar a modificação do horário antes da formatação da data.
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us", false);
Sendo assim nosso código fica do seguinte jeito:
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us", false);
int ano = 2019;
int mes = 05 ;
int dia = 01 ;
int hora = 13;
int minuto = 52;
int segundo = 22;
DateTime dataEntrada = new DateTime(ano,mes,dia,hora,minuto,segundo);
Console.WriteLine(dataEntrada);
E teremos a seguinte saida:
5/1/19 1:52:22 PM
Vamos fazer a troca do en-us para o pt-BR para que sempre que tivermos uma data ela fique no padrão brasileiro.
Thread.CurrentThread.CurrentCulture = new CultureInfo("pt-BR", false);
Mas toda vez que a gente tiver uma entrada ou saída nova temos que declarar isso no construtor e ainda assim continua um processo manual, podendo acontecer erro mais uma vez.
Para que este processo não seja todo manual, temos que procurar uma função que pegue o valor atual da hora e data para fazer essa atribuição. Mas qual função usar?
Vamos trabalhar com o Now
Vamos utilizar a função Now do Datetime, que pega a data e hora atual do seu sistema operacional, com isto ele faz a atribuição do horário para variável de maneira automática.
E como definimos para pegar a formatação do Brasil, não precisamos nos preocupar como vai vir a data e nem se ela será digitada errada.
DateTime dataEntrada = DateTime.Now;
Console.WriteLine(dataEntrada);
Nosso valor de saída vai ser a hora atual do meu sistema.
01/05/2019 14:20:11
Conclusão
Nós começando com datas mal formatadas, onde não havia padronização e nenhum tipo de validação para saber se a data está certa, o que dificultava o trabalho de quem precisava analisar esses valores depois.
Poderíamos utilizar uma String para fazer esta validação e formatação de data, mas isto seria muito complicado, pelas questões de tempo e de código, que ficaria gigante.
Para isso utilizamos o DateTime, que formata nossa lista de uma maneira mais padronizada e de fácil compreensão para quem vai analisar ela, as data vão ficar formatadas de maneira correta e de mais fácil compreensão.
E aí, o que achou do post? Fica até mais fácil trabalhar com datas no c# agora, não acha?Se quiser continuar estudando sobre o assunto, dê uma olhada em nossos cursos na Alura de C# continue aprendendo!