意外的日期计算结果
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 个字段定义:year
、month
和 day
。
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()”版本中省略了时区。
我有一种方法可以查看 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 个字段定义:year
、month
和 day
。
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()”版本中省略了时区。