简体   繁体   English

意外的日期计算结果

[英]Unexpected date calculation result

I have a method to view a calendar in Java that calculates the date by year, day of the week and week-number. 我有一种方法来查看Java中的日历,该日历按年,星期几和星期数计算日期。

Now when I calculates the dates from 2017 everything works. 现在,当我计算2017年的日期时,一切正常。 But when I calculates the dates from January 2018 it takes the dates of year 2017. 但是,当我计算2018年1月的日期时,需要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. 其结果是2018-01-02,应该是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 2018年1月1日

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. 根据当前年份设置周数( 1 to 53 )。
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. 如果您使用.withYear(year)更改年份,则Java LocalDate API无法调整此值,因为周数信息未保存在LocalDate实例中。

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

So to be precise, the important thing is that : 所以准确地说,重要的是:

.withYear(year) be invoked before .withYear(year)之前被调用

.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekNumber);

I want to mention, that there is another Problem(?) with LocalDate. 我想提一下,还有另一个问题(?)与LocalDate。

This Code does also create a wrong result: 此代码也会产生错误的结果:

    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;

If you change the creation of the year variable to 如果将year变量的创建更改为

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

the code returns the expected result. 代码返回预期的结果。 It seems as the way you construct a LocalDate matters. 看起来构建LocalDate的方式很重要。 I guess the timezone is omitted in the ".of()" version. 我想在“.of()”版本中省略了时区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM