I want to transform the following String:
private String cw = "35/19"
into 2 dates.
The start date can be formatted with:
private final DateTimeFormatter startOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
which when called returns: 26.08.2019
LocalDate.parse(cw, startOfWeekFormat).atStartOfDay();
But I struggle with the end of the week which is basically the start of the next week "36/19".
I tried to add plus 8 days, but that throws an exception:
private final DateTimeFormatter endOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 8)
.toFormatter();
LocalDateTime ldt=LocalDate.parse(cw, startOfWeekFormat)
.atStartOfDay()
.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
Demo:
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
public class Main {
public static void main(String[] args) {
String cw = "35/19";
final DateTimeFormatter startOfWeekFormat = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
LocalDateTime ldt=LocalDate.parse(cw, startOfWeekFormat)
.atStartOfDay()
.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
System.out.println(ldt);
}
}
Output:
2019-09-02T00:00
Another answer that adds a week, but in a different way:
I assume you always want the start date and the end date of a calendar week. You could write a method that returns a Map.Entry<LocalDate, LocalDate>
where the key is the start date and the value is the end date.
It could look like this:
public static Map.Entry<LocalDate, LocalDate> getStartAndEndOfCalendarWeek(String calendarWeek) {
DateTimeFormatter startOfWeekFormatter = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter();
LocalDate weekStart = LocalDate.parse(calendarWeek, startOfWeekFormatter);
LocalDate weekEnd = weekStart.plusWeeks(1);
return new AbstractMap.SimpleEntry<LocalDate, LocalDate>(weekStart, weekEnd);
}
Printing the result in a main
with your example String
like this
public static void main(String[] args) {
String cw = "35/19";
Map.Entry<LocalDate, LocalDate> calendarWeekStartAndEndDate
= getStartAndEndOfCalendarWeek(cw);
System.out.println(calendarWeekStartAndEndDate.getKey()
+ " - " + calendarWeekStartAndEndDate.getValue());
}
would output
2019-08-26 - 2019-09-02
I know this adds a week to the result of using your DateTimeFormatter
to parse the String
, but I don't think involving two different parsers or parsing actions would cause any benefit over adding a week.
If you want the starts of two consecutive calendar weeks, the make the addition add an additional day , like this:
LocalDate weekEnd = weekStart.plusWeeks(1).plusDays(1);
and if you want a LocalDateTime
(which is not quite clear to me if you really do), you could of course adjust the return type and use .atStartOfDay()
when you parse the weekStart
, the addition would stay the same.
I'd prefer an solution where I don't need to add the additional days to the result of the parsed string. Like a solution where the "plus(8)" is already included in the formatter.
That is not possible. You can't parse 2020-08-30
into 2020-08-31 or 2020-09-30. Just as well you cannot parse 35/19
into a date in week 36 of 2019.
I'm all in favour of half-open intervals, so I do see that it would be practical in your situation. Sorry that it isn't possible.
Link: Half-Open Interval in WolframMathWorld.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.