意外的日期计算结果 [英] Unexpected date calculation result

查看:65
本文介绍了意外的日期计算结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我的代码看起来像

import java.time.temporal.IsoFields;导入 java.time.temporal.ChronoField;导入 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;整数年 = 2018 年;LocalDate desiredDate = LocalDate.now().withYear(年).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 到 53).
如果您使用 .withYear(year) 更改年份,Java LocalDate API 无法调整此值,因为 中未保留周数信息LocalDate 实例.

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

public final class LocalDate实现 Temporal、TemporalAdjuster、ChronoLocalDate、Serializable {...私人最后一年;/*** 一年中的月份.*/私人最后一个短月;/*** 月份中的第几天.*/私人最后的短日;...}

所以准确地说,重要的是:

.withYear(year)

之前被调用

.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber);

I have a method to view a calendar in Java that calculates the date by year, day of the week and week-number.

Now when I calculates the dates from 2017 everything works. But when I calculates the dates from January 2018 it takes the dates of year 2017.

My code looks like

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

Which results in 2018-01-02 and it should be 2018-01-01. How is this possible?

解决方案

The order of invoked methods seems matter.
It you invoke them by descending time-granularity (year, week of week and day of week), you get the correct result :

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

Note that the problem origin comes from :

.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber)

that sets the week number (1 to 53) according to the current year.
The Java LocalDate API cannot adapt this value if then you change the year with .withYear(year) as the week number information is not kept in the LocalDate instance.

You can indeed see in LocalDate implementation that LocalDate instances are defined by only 3 field : year, month and 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;
    ...
}

So to be precise, the important thing is that :

.withYear(year) be invoked before

.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber);

这篇关于意外的日期计算结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆