Parsing with Java 8 DateTimeFormatter and Spanish Month Names

With the old, pre-Java 8, SimpleDateFormatI can do:

new java.text.SimpleDateFormat("MMM yyyy", new java.util.Locale("es", "ES")).parse("Mayo 2017")

to get a Datedate object with the names of the Spanish month.

How can I achieve the same with Java 8 and DateTimeFormatter?

I tried:

DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(new Locale("es", "ES")).ofPattern("MMM yyyy").parse("Mayo 2017")

but get only java.time.format.DateTimeParseException.

+4
source share
1 answer

The call ofLocalizedDateTime()can be deleted because at the end you call ofPattern(), create a different formatter with a completely different template (and the template returned ofLocalizedDateTime(FormatStyle.FULL)is very different from month year, so this is not exactly what you want).

: Mayo - , MMMM ( javadoc ). , DateTimeFormatter ( , , ), , .

, java.time.format.DateTimeFormatterBuilder:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // case insensitive
    .parseCaseInsensitive()
    // pattern with full month name (MMMM)
    .appendPattern("MMMM yyyy")
    // set locale
    .toFormatter(new Locale("es", "ES"));
// now it works
fmt.parse("Mayo 2017");

, java.time.YearMonth, ( ):

YearMonth ym = YearMonth.parse("Mayo 2017", fmt);
System.out.println(ym); // 2017-05

, SimpleDateFormat . , Date /, 1 ( JVM ).

API , . - parseDefaulting java.time.temporal.ChronoField:

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // case insensitive
    .parseCaseInsensitive()
    // pattern with full month name (MMMM)
    .appendPattern("MMMM yyyy")
    // default value for day of month
    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
    // default value for hour
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    // default value for minute
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    // set locale
    .toFormatter(new Locale("es", "ES"));

LocalDateTime, :

LocalDateTime dt = LocalDateTime.parse("Mayo 2017", fmt);
System.out.println(dt); // 2017-05-01T00:00

java.util.Date , SimpleDateFormat, LocalDateTime JVM Date:

Date javaUtilDate = Date.from(dt.atZone(ZoneId.systemDefault()).toInstant());

, JVM (ZoneId.systemDefault()), , SimpleDateFormat.


- YearMonth:

// in this case, the formatter doesn't need the default values
YearMonth ym = YearMonth.parse("Mayo 2017", fmt);
ZonedDateTime z = ym
    // set day of month to 1
    .atDay(1)
    // midnight at JVM default timezone
    .atStartOfDay(ZoneId.systemDefault());
Date javaUtilDate = date.from(z.toInstant());

, , .

API IANA ( Region/City, America/New_York Europe/Berlin), ZoneId.of("America/New_York"), . (, CST PST), .

( , ), ZoneId.getAvailableZoneIds().

+6

Source: https://habr.com/ru/post/1685970/


All Articles