Skip to content

Commit 9ad7603

Browse files
committed
#11 parte de DateTimeFormatter
1 parent 841bf8a commit 9ad7603

File tree

9 files changed

+348
-1
lines changed

9 files changed

+348
-1
lines changed

book/03-localization/sections/04-formats.asc

Lines changed: 175 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ No `Locale pt_BR`, temos o resultado esperado. Porém, no `Locale en_US` o `80,2
128128

129129
==== DecimalFormat
130130

131-
Enquanto `NumberFormat` permite utilizar formatos pré definidos, `DecimalFormat` permite uma personalização maior. Um exemplo de formato para o `DecimalFormat` é `\#\##,\###.\###`.
131+
Enquanto `NumberFormat` permite utilizar formatos predefinidos, `DecimalFormat` permite uma personalização maior. Um exemplo de formato para o `DecimalFormat` é `\#\##,\###.\###`.
132132
+
133133
* `#` preenche a posição com um número, ou omite se não houver nada.
134134
* `0` preenche a posição com um número, ou 0 se não houver nada.
@@ -186,8 +186,182 @@ Número 12.345,67 formatado
186186
----
187187

188188
==== DateTimeFormatter
189+
190+
O Java 8 traz a classe `DateTimeFormatter`, que possui várias formas de formatar e transformar `Data/Hora` em `String`, e vice-versa.
191+
192+
. É possível obter instâncias predefinidas de `DateTimeFormatter`, que representam formatos `ISO` ou `RFC`.
193+
+
194+
[source,java,indent=0]
195+
.{java-package}/formats/datetimeformatter/DateTimeFormatter_Predefined.java
196+
----
197+
include::{section-java-package}/formats/datetimeformatter/DateTimeFormatter_Predefined.java[tag=code]
198+
----
199+
+
200+
.Saída no console
201+
[source,console]
202+
----
203+
2019-08-06
204+
11:40:00
205+
2019-08-06T11:40:00
206+
2019-218
207+
2019-W32-2
208+
----
209+
210+
. É possível obter instâncias predefinidas de `DateTimeFormatter`, que representam formatos localizados, através da classe `FormatStyle`.
211+
+
212+
[source,java,indent=0]
213+
.{java-package}/formats/datetimeformatter/DateTimeFormatter_FormatStyle.java
214+
----
215+
include::{section-java-package}/formats/datetimeformatter/DateTimeFormatter_FormatStyle.java[tag=code]
216+
----
217+
+
218+
.Saída no console
219+
[source,console]
220+
----
221+
06/08/19 11:40
222+
06/08/2019 11:40:00
223+
06/08/19
224+
11:40
225+
----
226+
+
227+
O resultado depende de onde o código está sendo executado. Este código foi executado no `Locale` padrão `pt_BR`.
228+
229+
. É possível alterar o `Locale` utilizado pelo `DateTimeFormatter`.
230+
+
231+
[source,java,indent=0]
232+
.{java-package}/formats/datetimeformatter/DateTimeFormatter_Locale.java
233+
----
234+
include::{section-java-package}/formats/datetimeformatter/DateTimeFormatter_Locale.java[tag=code]
235+
----
236+
+
237+
.Saída no console
238+
[source,console]
239+
----
240+
8/6/19 11:40 AM
241+
Aug 6, 2019 11:40:00 AM
242+
----
243+
244+
. É possível obter instâncias personalizadas de `DateTimeFormatter`.
245+
+
246+
[source,java,indent=0]
247+
.{java-package}/formats/datetimeformatter/DateTimeFormatter_Custom.java
248+
----
249+
include::{section-java-package}/formats/datetimeformatter/DateTimeFormatter_Custom.java[tag=code]
250+
----
251+
+
252+
.Saída no console
253+
[source,console]
254+
----
255+
06 08 19 - 11 40 00
256+
----
257+
+
258+
Para criar um `DateTimeFormatter` personalizado, é necessário conhecer o que cada letra do formato representa. Seguem abaixo os mais importantes para o exame de certificação:
259+
+
260+
* `y` -> Ano (2019, 19)
261+
* `M` -> Mês (8, 08, Ago, Agosto)
262+
* `d` -> Dia (06)
263+
* `h` -> Hora em formato AM/PM
264+
* `H` -> Hora em formato 24H
265+
* `m` -> Minutos
266+
* `s` -> Segundos
267+
+
268+
Em geral (existem exceções), quanto mais letras forem utilizadas, mais extenso é o formato apresentado. Por exemplo:
269+
* `M` -> 8
270+
* `MM` -> 08
271+
* `MMM` -> Ago
272+
* `MMMM` -> Agosto
273+
274+
. Não é possível formatar uma Data/Hora caso o objeto fornecido não tenha os campos necessários, como tentar apresentar a Data e fornecer um `LocalTime`.
275+
+
276+
[source,java,indent=0]
277+
.{java-package}/formats/datetimeformatter/DateTimeFormatter_Error.java
278+
----
279+
include::{section-java-package}/formats/datetimeformatter/DateTimeFormatter_Error.java[tag=code]
280+
----
281+
+
282+
.Saída no console
283+
[source,console]
284+
----
285+
2019-08-06
286+
2019-08-06
287+
Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year
288+
at java.time.LocalTime.get0(LocalTime.java:679)
289+
at java.time.LocalTime.getLong(LocalTime.java:656)
290+
at java.time.format.DateTimePrintContext$1.getLong(DateTimePrintContext.java:205)
291+
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
292+
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2551)
293+
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2190)
294+
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
295+
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
296+
at java.time.LocalTime.format(LocalTime.java:1413)
297+
at org.j6toj8.localization.formats.datetimeformatter.DateTimeFormatter_Error.main(DateTimeFormatter_Error.java:18)
298+
----
299+
300+
. O mesmo erro pode ocorrer ao utilizar um formato personalizado.
301+
+
302+
[source,java,indent=0]
303+
.{java-package}/formats/datetimeformatter/DateTimeFormatter_ErrorCustom.java
304+
----
305+
include::{section-java-package}/formats/datetimeformatter/DateTimeFormatter_ErrorCustom.java[tag=code]
306+
----
307+
+
308+
.Saída no console
309+
[source,console]
310+
----
311+
11 40 00
312+
11 40 00
313+
Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
314+
at java.time.LocalDate.get0(LocalDate.java:680)
315+
at java.time.LocalDate.getLong(LocalDate.java:659)
316+
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
317+
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2551)
318+
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2190)
319+
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
320+
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
321+
at java.time.LocalDate.format(LocalDate.java:1691)
322+
at org.j6toj8.localization.formats.datetimeformatter.DateTimeFormatter_ErrorCustom.main(DateTimeFormatter_ErrorCustom.java:20)
323+
----
324+
+
325+
Nesse caso é lançada exceção porque `LocalDate` não possui hora, minuto ou segundo.
326+
327+
. Também é possível fazer o oposto: converter uma `String` em uma classe de `Data/Hora`. Para isso existem os métodos `parse`.
328+
+
329+
[source,java,indent=0]
330+
.{java-package}/formats/datetimeformatter/DateTimeFormatter_Parse.java
331+
----
332+
include::{section-java-package}/formats/datetimeformatter/DateTimeFormatter_Parse.java[tag=code]
333+
----
334+
+
335+
.Saída no console
336+
[source,console]
337+
----
338+
2019-08-06T11:40
339+
2019-08-06T11:40
340+
2019-08-06T11:40
341+
----
342+
343+
. Todos os métodos utilizados para `format` e `parse` também podem ser invocados diretamente na instância do `DateTimeFormatter`.
344+
+
345+
[source,java,indent=0]
346+
.{java-package}/formats/datetimeformatter/DateTimeFormatter_Inverted.java
347+
----
348+
include::{section-java-package}/formats/datetimeformatter/DateTimeFormatter_Inverted.java[tag=code]
349+
----
350+
+
351+
.Saída no console
352+
[source,console]
353+
----
354+
2019-08-06T11:40
355+
2019-08-06T11:40:00
356+
{},ISO resolved to 2019-08-06T11:40
357+
2019-08-06T11:40
358+
----
359+
+
360+
Porém, veja que ao utilizar o método `parse` diretamente no `DateTimeFormatter`, é necessário converter o resultado para um `LocalDateTime`.
361+
189362
==== DateFormat
190363

364+
191365
.Referências
192366
****
193367
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.j6toj8.localization.formats.datetimeformatter;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.format.DateTimeFormatter;
5+
6+
public class DateTimeFormatter_Custom {
7+
8+
public static void main(String[] args) {
9+
// tag::code[]
10+
LocalDateTime localDT = LocalDateTime.of(2019, 8, 6, 11, 40);
11+
12+
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd MM yy - HH mm ss");
13+
14+
System.out.println(localDT.format(customFormatter));
15+
// end::code[]
16+
}
17+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.j6toj8.localization.formats.datetimeformatter;
2+
3+
import java.time.LocalDate;
4+
import java.time.LocalDateTime;
5+
import java.time.LocalTime;
6+
import java.time.format.DateTimeFormatter;
7+
8+
public class DateTimeFormatter_Error {
9+
10+
public static void main(String[] args) {
11+
// tag::code[]
12+
LocalDate localDate = LocalDate.of(2019, 8, 6);
13+
LocalTime localTime = LocalTime.of(11, 40);
14+
LocalDateTime localDT = LocalDateTime.of(localDate, localTime);
15+
16+
System.out.println(localDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
17+
System.out.println(localDT.format(DateTimeFormatter.ISO_LOCAL_DATE));
18+
System.out.println(localTime.format(DateTimeFormatter.ISO_LOCAL_DATE)); // lança exceção pois não possui campos de data
19+
// end::code[]
20+
}
21+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.j6toj8.localization.formats.datetimeformatter;
2+
3+
import java.time.LocalDate;
4+
import java.time.LocalDateTime;
5+
import java.time.LocalTime;
6+
import java.time.format.DateTimeFormatter;
7+
8+
public class DateTimeFormatter_ErrorCustom {
9+
10+
public static void main(String[] args) {
11+
// tag::code[]
12+
LocalDate localDate = LocalDate.of(2019, 8, 6);
13+
LocalTime localTime = LocalTime.of(11, 40);
14+
LocalDateTime localDT = LocalDateTime.of(localDate, localTime);
15+
16+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH mm ss");
17+
18+
System.out.println(localDT.format(formatter));
19+
System.out.println(localTime.format(formatter));
20+
System.out.println(localDate.format(formatter)); // lança exceção pois não possui campos de hora
21+
// end::code[]
22+
}
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.j6toj8.localization.formats.datetimeformatter;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.format.DateTimeFormatter;
5+
import java.time.format.FormatStyle;
6+
7+
public class DateTimeFormatter_FormatStyle {
8+
9+
public static void main(String[] args) {
10+
// tag::code[]
11+
LocalDateTime localDT = LocalDateTime.of(2019, 8, 6, 11, 40);
12+
13+
DateTimeFormatter dateTimeShortFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
14+
DateTimeFormatter dateTimeMediumFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
15+
DateTimeFormatter dateShortFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
16+
DateTimeFormatter timeShortFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
17+
18+
System.out.println(localDT.format(dateTimeShortFormatter));
19+
System.out.println(localDT.format(dateTimeMediumFormatter));
20+
System.out.println(localDT.format(dateShortFormatter));
21+
System.out.println(localDT.format(timeShortFormatter));
22+
// end::code[]
23+
}
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.j6toj8.localization.formats.datetimeformatter;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.format.DateTimeFormatter;
5+
import java.time.temporal.TemporalAccessor;
6+
7+
public class DateTimeFormatter_Inverted {
8+
9+
public static void main(String[] args) {
10+
// tag::code[]
11+
LocalDateTime localDT = LocalDateTime.of(2019, 8, 6, 11, 40);
12+
System.out.println(localDT);
13+
14+
String format = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(localDT);
15+
System.out.println(format);
16+
17+
TemporalAccessor parse = DateTimeFormatter.ISO_LOCAL_DATE_TIME.parse(format);
18+
System.out.println(parse);
19+
System.out.println(LocalDateTime.from(parse));
20+
// end::code[]
21+
}
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.j6toj8.localization.formats.datetimeformatter;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.format.DateTimeFormatter;
5+
import java.time.format.FormatStyle;
6+
import java.util.Locale;
7+
8+
public class DateTimeFormatter_Locale {
9+
10+
public static void main(String[] args) {
11+
// tag::code[]
12+
LocalDateTime localDT = LocalDateTime.of(2019, 8, 6, 11, 40);
13+
14+
DateTimeFormatter shortFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
15+
DateTimeFormatter mediumFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
16+
17+
shortFormatter = shortFormatter.withLocale(Locale.US);
18+
mediumFormatter = mediumFormatter.withLocale(Locale.US);
19+
20+
System.out.println(localDT.format(shortFormatter));
21+
System.out.println(localDT.format(mediumFormatter));
22+
// end::code[]
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.j6toj8.localization.formats.datetimeformatter;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.format.DateTimeFormatter;
5+
import java.time.format.FormatStyle;
6+
7+
public class DateTimeFormatter_Parse {
8+
9+
public static void main(String[] args) {
10+
// tag::code[]
11+
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd MM yy - HH mm ss");
12+
DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
13+
DateTimeFormatter shortFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
14+
15+
LocalDateTime parseCustom = LocalDateTime.parse("06 08 19 - 11 40 00", customFormatter);
16+
LocalDateTime parseIso = LocalDateTime.parse("2019-08-06T11:40:00", isoFormatter);
17+
LocalDateTime parseShort = LocalDateTime.parse("06/08/19 11:40", shortFormatter);
18+
19+
System.out.println(parseCustom);
20+
System.out.println(parseIso);
21+
System.out.println(parseShort);
22+
// end::code[]
23+
}
24+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.j6toj8.localization.formats.datetimeformatter;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.format.DateTimeFormatter;
5+
6+
public class DateTimeFormatter_Predefined {
7+
8+
public static void main(String[] args) {
9+
// tag::code[]
10+
LocalDateTime localDT = LocalDateTime.of(2019, 8, 6, 11, 40);
11+
System.out.println(localDT.format(DateTimeFormatter.ISO_LOCAL_DATE));
12+
System.out.println(localDT.format(DateTimeFormatter.ISO_LOCAL_TIME));
13+
System.out.println(localDT.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
14+
System.out.println(localDT.format(DateTimeFormatter.ISO_ORDINAL_DATE));
15+
System.out.println(localDT.format(DateTimeFormatter.ISO_WEEK_DATE));
16+
// end::code[]
17+
}
18+
}

0 commit comments

Comments
 (0)