1. ZonedDateTimeaula

Existe outra classe muito interessante na API Date Time: a ZonedDateTimeclasse. Seu principal objetivo é facilitar o trabalho com datas em diferentes fusos horários.

LocalDateé ótimo para representar datas. Por exemplo, aniversários. Meu aniversário é dia 15 de março, não importa onde eu esteja. Este é um exemplo de data.

LocalTimeé ótimo para descrever o tempo, como o horário definido em um despertador: eu coloco o alarme para as 5h e não importa onde estou. 5:00 da manhã é 5:00 da manhã. Este é um exemplo de trabalho com o tempo.

Agora, digamos que estamos escrevendo um aplicativo que reserva voos. Os aviões decolam e chegam com base no horário local. O avião fica no ar por um tempo fixo, mas os fusos horários podem mudar.

Fusos horários

A propósito, os fusos horários são uma verdadeira bagunça. E se você pensa que existem 24 fusos horários, está muito enganado.

Por exemplo, o horário na Índia difere do horário de Greenwich em cinco horas e meia: GMT+5:30. Alguns países mudam para o horário de verão e outros não. Além disso, diferentes países mudam para o horário de verão em diferentes épocas do ano.

E alguns países aprovam leis que cancelam o horário de verão, ou o reintroduzem, ou o cancelam novamente.

De qualquer forma, o mundo tem fusos horários e dentro de cada fuso horário existe uma hora. O horário em diferentes zonas pode coincidir durante determinados períodos do ano e diferir em outros períodos. Os fusos horários geralmente recebem o nome das principais cidades localizadas neles: Europe/Monaco, Asia/Singapore, mas também há exceções - US/Pacific.

Oficialmente, existem 599 fusos horários no momento. Pense nisso: 599. Está longe de ser 24. Bem-vindo ao mundo global.

A ZoneIdclasse do java.timepacote é usada para armazenar um fuso horário em Java.

A propósito, ele possui um getAvailableZoneIds()método estático, que retorna o conjunto de todos os fusos horários conhecidos atualmente. Para obter uma lista de todas as zonas, você precisa escrever o seguinte código:

Código Saída do console (parcial)
for (String s: ZoneId.getAvailableZoneIds())
   System.out.println(s);
Asia/Aden
America/Cuiaba
Etc/GMT+9
Etc/GMT+8

Para obter um ZoneIdobjeto pelo nome, você precisa usar o of()método estático;

Código Observação
ZoneId zone = ZoneId.of("Africa/Cairo");
Cairo


2. Criando um ZonedDateTimeobjeto

Ao criar um ZonedDateTimeobjeto, você precisa chamar o now()método estático da classe e passar um ZoneIdobjeto para ele.

Código Saída do console
ZoneId zone = ZoneId.of("Africa/Cairo");
ZonedDateTime time = ZonedDateTime.now(zone);
System.out.println(time);


2019-02-22T11:37:58.074816+02:00[Africa/Cairo]

Se você não passar um ZoneIdobjeto para o now()método (e isso é permitido), o fuso horário é determinado automaticamente com base nas configurações do computador que está executando o programa.

Exemplo:

Código Saída do console
ZonedDateTime time = ZonedDateTime.now();
System.out.println(time);

2019-02-22T13:39:05.70842+02:00[Europe/Helsinki]

Convertendo uma data global em uma local

Uma das características interessantes do ZonedDateTimeé sua capacidade de converter para uma data e hora locais. Exemplo:

ZoneId zone = ZoneId.of("Africa/Cairo");
ZonedDateTime cairoTime = ZonedDateTime.now(zone);

LocalDate localDate = cairoTime.toLocalDate();
LocalTime localTime = cairoTime.toLocalTime();
LocalDateTime localDateTime = cairoTime.toLocalDateTime();

3. Trabalhando com o tempo

Como a LocalDateTimeclasse, a ZonedDateTimeclasse tem várias maneiras de obter elementos individuais de uma data e hora. Aqui está uma lista desses métodos:

int getYear()
Retorna o ano de uma data específica
Month getMonth()
Retorna o mês da data: uma das várias constantes —JANUARY, FEBRUARY, ...;
int getMonthValue()
Retorna o índice do mês da data. janeiro == 1
int getDayOfMonth()
Retorna o índice do dia do mês
DayOfWeek getDayOfWeek()
Retorna o dia da semana: uma das várias constantes —MONDAY, TUESDAY, ...;
int getDayOfYear()
Retorna o índice do dia do ano
int getHour()
Retorna as horas
int getMinute()
Retorna os minutos
int getSecond()
Retorna os segundos
int getNano()
Retorna os nanossegundos

Todos os métodos são perfeitamente análogos aos métodos da LocalDateTimeclasse. E, claro, a ZonedDateTimeclasse tem métodos que permitem trabalhar com datas e horas. Dito isso, o objeto no qual os métodos são chamados não muda. Em vez disso, eles retornam um novo ZonedDateTimeobjeto:

Métodos Descrição
plusYears(int)
Adiciona anos à data
plusMonths(int)
Adiciona meses à data
plusDays(int)
Adiciona dias à data
plusHours(int)
Adiciona horas
plusMinutes(int)
Adiciona minutos
plusSeconds(int)
Adiciona segundos
plusNanos(int)
Adiciona nanossegundos
minusYears(int)
Subtrai anos da data
minusMonths(int)
Subtrai meses da data
minusDays(int)
Subtrai dias da data
minusHours(int)
Subtrai horas
minusMinutes(int)
Subtrai minutos
minusSeconds(int)
Subtrai segundos
minusNanos(int)
Subtrai nanossegundos

Não daremos exemplos, pois pensamos que tudo aqui é claro por analogia com as classes que acabamos de considerar.