I have to parse date using the following format: "201710" where 10 - week of year number. I tried to implement it in this way:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyw");
java.time.LocalDate startDate = java.time.LocalDate.parse("201710", formatter);
System.out.println(startDate);
But it throws exception:
java.time.format.DateTimeParseException: Text '201710' could not be parsed at index 0
And after that I need to get first and last day of week from LocalDate object. e.g "201710" - 05.03 12.03 (first day of week needs to be Sunday).
The accepted answer of @Kayaman is not correct because you cannot mix standard date representations (using yyyy = year-of-era) and week-date representations (using ww = week of week-based year). The subtile difference between a standard calendar year and a weekbased year is relevant near the start or end of a calendar year. Conclusion: Don't use the symbol "y", but rather the symbol "Y". Counter example for the input "201501":
Correct solution
DateTimeFormatter formatter =
new DateTimeFormatterBuilder()
.appendValue(WeekFields.ISO.weekBasedYear(), 4)
.appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2)
.parseDefaulting(ChronoField.DAY_OF_WEEK, 1)
.toFormatter();
LocalDate startDate = LocalDate.parse("201501", formatter);
System.out.println(startDate); // 2014-12-29
Based on the proposal of @Kayaman:
DateTimeFormatter dtf =
new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2)
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
System.out.println(LocalDate.parse("201501", dtf)); // 2015-01-05 (wrong)
The resulting dates are different! The difference is caused by the definition of the calendar year which always starts on first of January while a week-based year always starts on Monday (ISO-8601-definition) using the first week of calendar year which has at least 4 days.
Additional note a): Java-8 does not manage adjacent digit parsing of localizible fields like the week-based fields (see also the associated JDK issue), therefore I have chosen the builder-based solution instead of defining the pattern "YYYYww" (Java-9 promises a solution, however). But even with Java-9, a build-based approach is still necessary because of the need to define a default for the missing day-of-week (here: setting to Monday).
Additional note b): If you are looking for a true type for the combination of week-based year and week-of-year and use LocalDate
just as a workaround for this missing type, well, you can find such a type in 3rd-party libraries, either in Threeten-Extra or in my library Time4J. Example:
ChronoFormatter<CalendarWeek> cf =
ChronoFormatter.ofPattern(
"YYYYww",
PatternType.CLDR,
Locale.ROOT,
CalendarWeek.chronology()
);
CalendarWeek cw = cf.parse("201501");
System.out.println(cw); // 2015-W01
System.out.println(cw.at(Weekday.MONDAY)); // 2014-12-29