如何将日历周的开始和结束作为 LocalDateTime (java 8)

How to get the start and end of a calendar week as LocalDateTime (java 8)

我想转换以下字符串:

private String cw = "35/19" 

分为 2 个日期。

开始日期的格式可以是:

private final DateTimeFormatter startOfWeekFormat = new DateTimeFormatterBuilder()
   .appendPattern("ww/YY")
   .parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
   .toFormatter();

调用时 returns:2019 年 8 月 26 日

LocalDate.parse(cw, startOfWeekFormat).atStartOfDay();

但我很难接受周末,这基本上是下周“36/19”的开始。

我试着加上 8 天,但抛出异常:

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));

演示:

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);
    }
}

输出:

2019-09-02T00:00

另一个增加一周但方式不同的答案:

我假设您总是想要日历周的开始日期和结束日期。您可以编写一个 return 是 Map.Entry<LocalDate, LocalDate> 的方法,其中键是开始日期,值是结束日期。

它可能看起来像这样:

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);
}

使用您的示例 Stringmain 中打印结果

public static void main(String[] args) {
    String cw = "35/19";
    Map.Entry<LocalDate, LocalDate> calendarWeekStartAndEndDate
                                    = getStartAndEndOfCalendarWeek(cw);
    System.out.println(calendarWeekStartAndEndDate.getKey() 
            + " - " + calendarWeekStartAndEndDate.getValue());
}

会输出

2019-08-26 - 2019-09-02

我知道这会使使用您的 DateTimeFormatter 解析 String 的结果增加一周,但我不认为涉及两个不同的解析器或解析操作会带来任何好处一个星期。

如果您想要连续两个日历周的开始,则添加额外的一天,如下所示:

LocalDate weekEnd = weekStart.plusWeeks(1).plusDays(1);

如果你想要 LocalDateTime(如果你真的想要,我不太清楚),你当然可以调整 return 类型并在你使用 .atStartOfDay() 时使用解析 weekStart,添加将保持不变。

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.

那是不可能的。您无法将 2020-08-30 解析为 2020-08-31 或 2020-09-30。同样,您无法将 35/19 解析为 2019 年第 36 周的日期。

我完全赞成 half-open 间隔,所以我确实看到它在您的情况下很实用。抱歉,这不可能。

Link:Half-Open Interval 在 WolframMathWorld 中。