1. Mudando de Dateclasse para Calendarclasse

Os programadores adoraram a Dateclasse por sua simplicidade e suporte aos padrões Unix, mas como você sabe, toda rosa tem seus espinhos.

Os programadores queriam uma Dateclasse "inteligente". E eles conseguiram o que queriam na forma da Calendaraula. Foi concebido como uma forma não só de armazenar datas, mas também de realizar operações difíceis com datas.

O nome completo da Calendarclasse é java.util.Calendar. Não se esqueça de adicioná-lo a uma instrução de importação se decidir usá-lo em seu código.

Você pode criar um Calendarobjeto com este comando:

Calendar date = Calendar.getInstance();

O método estático getInstance()da Calendarclasse cria um Calendarobjeto inicializado com a data atual. O calendário que você deseja será criado com base nas configurações do computador que executa o programa.

Ou, mais precisamente, o calendário que você obtém... Isso ocorre porque os humanos na Terra não estão limitados a um único calendário. Em vez disso, eles usam muitos. E quase todos eles estão associados a alguma religião ou país. A Calendarclasse suporta 3 deles:

Calendário Descrição
Calendário gregoriano calendário gregoriano cristão
calendário budista calendário budista
Calendário Imperial Japonês calendário imperial japonês

Mas também existem calendários chinês e árabe. Basicamente, trabalhar com o tempo não é tão fácil quanto parece.

No calendário chinês, o ano é oficialmente 4716 no momento em que esta lição foi escrita. E de acordo com o calendário muçulmano, o ano é 1398. Bem-vindo ao grande mundo, meu amigo programador.

2. Criando um objeto de calendário

Usaremos o calendário gregoriano, pois é o mais comum do mundo. Pelo menos até a China comprar a Oracle e tornar o calendário chinês o principal.

Você pode criar um objeto de calendário com qualquer data usando uma instrução como esta:

Calendar date = new GregorianCalendar(year, month, day);

Sim, você tem que escrever GregorianCalendarsempre. Em vez de Calendar, você também pode escrever GregorianCalendar- isso também funcionará. Mas escrever apenas Calendaré mais curto.

O ano deve ser escrito por completo, por exemplo, você não pode escrever 19 em vez de 2019. Os meses ainda são numerados a partir do zero. Mas, como antes, os dias do mês não são numerados a partir do zero. Nerds!

Para definir a hora e a data, você precisa passar a hora como argumentos adicionais:

... = new GregorianCalendar(year, month, day, hours, minutes, seconds);

Você pode até passar em milissegundos, se necessário. Eles são o parâmetro após o número de segundos.

3. Exibindo um objeto de calendário na tela

Se você simplesmente imprimir um objeto de calendário na tela, não ficará muito satisfeito com o resultado.

Código
Calendar calendar = new GregorianCalendar(2019, 03, 12);
System.out.println(calendar);
Saída do console
java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Helsinki",offset=7200000,dstSavings=3600000,useDaylight=true,transitions=118,lastRule=java.util.SimpleTimeZone[id=Europe/Helsinki,offset=7200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=2019,MONTH=3,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=12,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]

O que você deve ter em mente aqui é que um calendário é um calendário, não uma data : ele tem todos os tipos de configurações que serão exibidas na tela.

Seria apropriado usar um SimpleDateFormatobjeto para exibir um calendário, mas até que o estudemos, você pode usar este hack de vida.

Date date = calendar.getTime();

Um Calendarobjeto pode ser facilmente convertido em um Dateobjeto e você já sabe como exibir um Dateobjeto. Você pode usar um código como este para converter um Calendarobjeto em Date:

Usando o getTime()método:

Código Saída do console
Calendar calendar = new GregorianCalendar(2019, 03, 12);
System.out.println(calendar.getTime());
 Fri Apr 12 00:00:00 EEST 2019

Isso é uma questão bem diferente, não é?

4. Trabalhando com elementos de uma data

Para obter um elemento específico de uma data (por exemplo, ano, mês, ...), a Calendarclasse possui o get()método. É um método único, mas possui parâmetros:

int month = calendar.get(Calendar.MONTH);

Onde calendaré uma Calendarvariável e MONTHé um campo constante da Calendarclasse.

Você passa um dos Calendarcampos constantes da classe como um argumento para o getmétodo e obtém o valor desejado como resultado.

Exemplos

Código Descrição
Calendar calendar = Calendar.getInstance();

int era = calendar.get(Calendar.ERA);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);

int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);


era (antes ou depois da era comum)
ano
mês
dia do mês

dia da semana
horas
minutos
segundos

Para alterar um elemento de uma data, use o setmétodo:

calendar.set(Calendar.MONTH, value);

Onde calendaré uma Calendarvariável e MONTHé um campo constante da Calendarclasse.

Ao trabalhar com seto método, você passa um dos Calendarcampos constantes da classe como o primeiro argumento e o novo valor como o segundo argumento.

Exemplos

Código Descrição
Calendar calendar = new GregorianCalendar();

calendar.set(Calendar.YEAR, 2019);
calendar.set(Calendar.MONTH, 6);
calendar.set(Calendar.DAY_OF_MONTH, 4);
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 15);
calendar.set(Calendar.SECOND, 0);

System.out.println(calendar.getTime());


ano = 2019
mês = julho (numerado a partir de 0)
4º dia
horas
minutos
segundos

5. Constantes da Calendarclasse

Os campos constantes da Calendarclasse não se limitam àqueles para nomear elementos de uma data. Parece haver campos para todas as ocasiões.

Calendar date = new GregorianCalendar(2019, Calendar.JANUARY, 31);

Por exemplo, existem campos constantes para se referir a meses:

E também os dias da semana:

Calendar calendar = new GregorianCalendar(2019, Calendar.JANUARY, 31);
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY)
{
   System.out.println("It's Friday");
}

Não vamos listar tudo. Só não queremos que você fique surpreso se vir constantes como essa no código.

O uso de constantes torna o código mais legível, e é por isso que os programadores as usam. E os meses são numerados a partir do zero também para melhorar a legibilidade. Ou não.

6. Alterar a data em um Calendarobjeto

A Calendarclasse tem um método que permite que você opere em um encontro de maneiras mais inteligentes. Por exemplo, você pode adicionar um ano, um mês ou vários dias a uma data. Ou levá-los embora. Este método é chamado add(). Trabalhar com ele fica assim:

calendar.add(Calendar.MONTH, value);

Onde calendaré uma Calendarvariável e MONTHé um campo constante da Calendarclasse.

Ao trabalhar com addo método, você passa um dos Calendarcampos constantes da classe como primeiro argumento e como segundo argumento — o novo valor a ser adicionado.

Este é outro método inteligente. Vamos ver o quão inteligente é:

Código
Calendar calendar = new GregorianCalendar(2019, Calendar.FEBRUARY, 27);
calendar.add(Calendar.DAY_OF_MONTH, 2);
System.out.println(calendar.getTime());
Saída do console
Fri Mar 01 00:00:00 EET 2019

Este método entende que fevereiro de 2019 tem apenas 28 dias, então a data resultante é 1º de março.

Agora vamos tirar 2 meses! O que devemos obter? 27 de dezembro de 2018! Vamos verificar agora.

Para realizar uma operação que resulte em uma data anterior, você precisa passar um valor negativo para o add()método:

Código
Calendar calendar = new GregorianCalendar(2019, Calendar.FEBRUARY, 27);
calendar.add(Calendar.MONTH, -2);
System.out.println(calendar.getTime());
Saída do console
Thu Dec 27 00:00:00 EET 2018

Funciona!

Este método considera as diferentes durações dos meses, bem como os anos bissextos. Em suma, um ótimo método. É exatamente o que a maioria dos programadores que trabalham com datas precisam.

7. Elementos rolantes de uma data

Mas às vezes há situações em que não queremos esse comportamento inteligente, por exemplo, você deseja fazer algo em uma parte do encontro sem alterar todo o resto.

A Calendarclasse tem o roll()método especial para isso. Sua assinatura é igual ao add()método, mas este método altera apenas um elemento da data, deixando o restante inalterado.

Exemplo:

Código
Calendar calendar = new GregorianCalendar(2019, Calendar.FEBRUARY, 27);
calendar.roll(Calendar.MONTH, -2);
System.out.println(calendar.getTime());
Saída do console
Fri Dec 27 00:00:00 EET 2019

Mudamos o mês, mas o ano e a data permaneceram inalterados.