Unexpected date calculation result

那年仲夏 提交于 2019-12-10 03:14:46

问题


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?


回答1:


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



回答2:


I want to mention, that there is another Problem(?) with 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

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

the code returns the expected result. It seems as the way you construct a LocalDate matters. I guess the timezone is omitted in the ".of()" version.



来源:https://stackoverflow.com/questions/47259213/unexpected-date-calculation-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!