意外的日期计算结果

Unexpected date calculation result

我有一种方法可以查看 Java 中的日历,该日历按年份、星期几和周数计算日期。

现在,当我计算 2017 年的日期时,一切正常。但是当我计算从 2018 年 1 月开始的日期时,它需要 2017 年的日期。

我的代码看起来像

import java.time.temporal.IsoFields;
import java.time.temporal.ChronoField;
import java.time.LocalDate;

// .....

LocalDate desiredDate = LocalDate.now()
                    .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 1)
                    .with(ChronoField.DAY_OF_WEEK, 1)
                    .withYear(2018);

结果为 2018-01-02,应该是 2018-01-01。这怎么可能?

调用方法的顺序似乎很重要。
如果您通过降低时间粒度(年、星期几和星期几)来调用它们,您会得到正确的结果:

long weekNumber = 1;
long dayOfWeek = 1;
int year = 2018;

LocalDate desiredDate = LocalDate.now()
    .withYear(year)
    .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)
    .with(ChronoField.DAY_OF_WEEK, dayOfWeek );

System.out.println(desiredDate);

2018-01-01

注意问题来源来自:

.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)

根据当前年份设置周数(1 to 53)。
Java LocalDate API 无法调整此值,如果您使用 .withYear(year) 更改年份,因为 [=15] 中未保留周数信息=]实例.

您确实可以在 LocalDate 实现中看到 LocalDate 个实例仅由 3 个字段定义:yearmonthday

public final class LocalDate
        implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {
    ...
    private final int year;
    /**
     * The month-of-year.
     */
    private final short month;
    /**
     * The day-of-month.
     */
    private final short day;
    ...
}

准确地说,重要的是:

.withYear(year)

之前调用
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber);

我想提一下,LocalDate 还有另一个问题(?)。

此代码也产生了错误的结果:

    int jahr = Integer.parseInt(str[0]);
    int woche = Integer.parseInt(str[1]);

    LocalDate year = LocalDate.of(jahr, 1, 1);
    LocalDate week = year.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, woche);
    LocalDate day = week.with(wochentag);
    return day;

如果将 year 变量的创建更改为

 LocalDate year = LocalDate.now().withYear(jahr);

代码 returns 预期结果。看起来您构建 LocalDate 的方式很重要。我想在“.of()”版本中省略了时区。