Guia para DateTimeFormatter
1. Visão geral
Neste tutorial, revisaremos a classe Java 8DateTimeFormatter e seus padrões de formatação. Também discutiremos os possíveis casos de uso para esta classe.
Podemos usarDateTimeFormatter para formatar datas e horas uniformemente em um aplicativo com padrões predefinidos ou definidos pelo usuário.
2. DateTimeFormatter com instâncias predefinidas
DateTimeFormatter comes with multiple predefined date/time formats que seguem os padrões ISO e RFC. Por exemplo, podemos usar a instânciaISO_LOCAL_DATE para analisar uma data como ‘2018-03-09’:
DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.of(2018, 3, 9));
Para analisar uma data com um deslocamento, podemos usarISO_OFFSET_DATE para obter uma saída como ‘2018-03-09-03: 00’:
DateTimeFormatter.ISO_OFFSET_DATE.format(LocalDate.of(2018, 3, 9).atStartOfDay(ZoneId.of("UTC-3")));
Most of the predefined instances of the DateTimeFormatter class are focused on the ISO-8601 standard. ISO-8601 é um padrão internacional para formatação de data e hora.
Há, no entanto, uma instância predefinida diferente que analisa RFC-1123, Requisito para Hosts da Internet,published pela IETF:
DateTimeFormatter.RFC_1123_DATE_TIME.format(LocalDate.of(2018, 3, 9).atStartOfDay(ZoneId.of("UTC-3")));
Este snippet gera ‘Fri, 9 Mar 2018 00:00:00 -0300’.
Às vezes, temos que manipular a data que recebemos comoString de um formato conhecido. Podemos usar o métodoparse():
LocalDate.from(DateTimeFormatter.ISO_LOCAL_DATE.parse("2018-03-09")).plusDays(3);
O resultado deste snippet de código é uma representaçãoLocalDate para 12 de março de 2018.
3. DateTimeFormatter comFormatStyle
Às vezes, podemos querer imprimir datas de maneira legível por humanos.
Nesses casos, podemos usarjava.time.format.FormatStyle enum (FULL, LONG, MEDIUM, SHORT) valores com nossosDateTimeFormatter:
LocalDate anotherSummerDay = LocalDate.of(2016, 8, 23);
System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(anotherSummerDay));
System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(anotherSummerDay));
System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(anotherSummerDay));
System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(anotherSummerDay));
A saída desses diferentes estilos de formatação da mesma data é:
Tuesday, August 23, 2016
August 23, 2016
Aug 23, 2016
8/23/16
Também podemos usar estilos de formatação predefinidos para data e hora. Para usarFormatStyle com o tempo, teremos que usar a instânciaZonedDateTime, caso contrário, umDateTimeException será lançado:
LocalDate anotherSummerDay = LocalDate.of(2016, 8, 23);
LocalTime anotherTime = LocalTime.of(13, 12, 45);
ZonedDateTime zonedDateTime = ZonedDateTime.of(anotherSummerDay, anotherTime, ZoneId.of("Europe/Helsinki"));
System.out.println(
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL)
.format(zonedDateTime));
System.out.println(
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.format(zonedDateTime));
System.out.println(
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.format(zonedDateTime));
System.out.println(
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
.format(zonedDateTime));
Observe que usamos o métodoofLocalizedDateTime() deDateTimeFormatter desta vez.
E a saída que obtemos é:
Tuesday, August 23, 2016 1:12:45 PM EEST
August 23, 2016 1:12:45 PM EEST
Aug 23, 2016 1:12:45 PM
8/23/16 1:12 PM
Também podemos usarFormatStyle para analisar uma data e horaString convertendo-a emZonedDateTime, por exemplo.
Podemos então usar o valor analisado para manipular a variável de data e hora:
ZonedDateTime dateTime = ZonedDateTime.from(
DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL)
.parse("Tuesday, August 23, 2016 1:12:45 PM EET"));
System.out.println(dateTime.plusHours(9));
A saída desse snippet é "2016-08-23T22: 12: 45 + 03: 00 [Europa / Bucareste]", observe que o horário foi alterado para "22:12:45".
4. DateTimeFormatter com formatos personalizados
Predefined and built-in formatters and styles can cover a lot of situations. No entanto, às vezes precisamos formatar uma data e hora de maneira um pouco diferente. É quando os padrões de formatação personalizados entram em cena.
4.1. DateTimeFormatter para data
Suponha que desejamos apresentar um objetojava.time.LocalDate usando um formato europeu regular como 31.12.2018. Para fazer isso, podemos chamar o método de fábricaDateTimeFormatter.ofPattern(“dd.MM.yyyy”).
Isso criará uma instânciaDateTimeFormatter apropriada que podemos usar para formatar nossa data:
String europeanDatePattern = "dd.MM.yyyy";
DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern(europeanDatePattern);
System.out.println(europeanDateFormatter.format(LocalDate.of(2016, 7, 31)));
A saída desse snippet de código será "31.07.2016".
Existem muitas cartas-padrão diferentes que podemos usar para criar um formato para datas que atendam às nossas necessidades:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
u year year 2004; 04
y year-of-era year 2004; 04
M/L month-of-year number/text 7; 07; Jul; July; J
d day-of-month number 10
Este é um extrato da classeofficial Java documentation aDateTimeFormatter.
The number of letters in the pattern format is significant.
Se usarmos um padrão de duas letras para o mês, obteremos uma representação de dois dígitos. Se o número do mês for menor que 10, será preenchido com um zero. Quando não precisamos do preenchimento mencionado com zeros, podemos usar um padrão de uma letra "M", que mostrará janeiro como "1".
Se usarmos um padrão de quatro letras para o mês, "MMMM", obteremos uma representação "completa". No nosso exemplo, é "julho". Um padrão de cinco letras, "MMMMM", fará com que o formatador use a "forma estreita". No nosso caso, "J" seria usado.
Da mesma forma, o padrão de formatação personalizado também pode ser usado para analisar uma String que contém uma data:
DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
System.out.println(LocalDate.from(europeanDateFormatter.parse("15.08.2014")).isLeapYear());
Este trecho de código verifica se a data “15.08.2014” é de um ano bissexto, e não é.
4.2. DateTimeFormatter para tempo
Também existem cartas de padrões que podem ser usadas para padrões de tempo:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
H hour-of-day (0-23) number 0
m minute-of-hour number 30
s second-of-minute number 55
S fraction-of-second fraction 978
n nano-of-second number 987654321
É muito simples usarDateTimeFormatter para formatar uma instânciajava.time.LocalTime. Suponha que desejemos mostrar o tempo (horas, minutos e segundos) delimitado por dois pontos:
String timeColonPattern = "HH:mm:ss";
DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern);
LocalTime colonTime = LocalTime.of(17, 35, 50);
System.out.println(timeColonFormatter.format(colonTime));
Isso gerará a saída “17:35:50“.
Se quisermos adicionar milissegundos à saída, devemos adicionar “SSS” ao padrão:
String timeColonPattern = "HH:mm:ss SSS";
DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern);
LocalTime colonTime = LocalTime.of(17, 35, 50).plus(329, ChronoUnit.MILLIS);
System.out.println(timeColonFormatter.format(colonTime));
O que dá a saída “17:35:50 329“.
Observe que "HH" é um padrão da hora do dia que gera a saída de 0 a 23. Quando queremos mostrar AM / PM, devemos usar minúsculas "hh" por horas e adicionar um padrão "a":
String timeColonPattern = "hh:mm:ss a";
DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern);
LocalTime colonTime = LocalTime.of(17, 35, 50);
System.out.println(timeColonFormatter.format(colonTime));
A saída gerada é “05:35:50 PM“.
Podemos querer analisar o tempoString com nosso formatador personalizado e verificar se é antes do meio-dia:
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss a");
System.out.println(LocalTime.from(timeFormatter.parse("12:25:30 AM")).isBefore(LocalTime.NOON));
A saída deste último trecho mostra que o tempo determinado é realmente antes do meio dia.
4.3. DateTimeFormatter para fusos horários
Often we want to see a time zone of some specific date-time variable. Se acontecer de usarmos a data e hora com base em Nova York (UTC -4), podemos usar a letra-padrão “z” para o nome do fuso horário:
String newYorkDateTimePattern = "dd.MM.yyyy HH:mm z";
DateTimeFormatter newYorkDateFormatter = DateTimeFormatter.ofPattern(newYorkDateTimePattern);
LocalDateTime summerDay = LocalDateTime.of(2016, 7, 31, 14, 15);
System.out.println(newYorkDateFormatter.format(ZonedDateTime.of(summerDay, ZoneId.of("UTC-4"))));
Isso gerará a saída "31.07.2016 14:15 UTC-04: 00".
Podemos analisar seqüências de data e hora com fusos horários, como fizemos anteriormente:
DateTimeFormatter zonedFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm z");
System.out.println(ZonedDateTime.from(zonedFormatter.parse("31.07.2016 14:15 GMT+02:00")).getOffset().getTotalSeconds());
A saída desse código é “7200” segundos, ou 2 horas, como esperávamos.
Temos que nos certificar de que fornecemos uma data e hora corretaString para o métodoparse(). Se passarmos “31.07.2016 14:15”, sem fuso horário para ozonedFormatter do último trecho de código, obteremos umDateTimeParseException.
5. Conclusão
In this tutorial, we’ve discussed how to use the DateTimeFormatter class for format dates and times. Usamos padrões de exemplo da vida real que muitas vezes surgem quando trabalhamos com instâncias de data e hora.
Podemos descobrir mais sobre a API Java 8Date/Time emprevious tutorials. Como sempre, o código-fonte usado no tutorial está disponívelover on GitHub.