Неожиданный результат расчета даты
У меня есть метод для просмотра календаря в Java, который рассчитывает дату по году, день недели и номер недели.
Теперь, когда я рассчитываю даты с 2017 года, все работает. Но когда я рассчитываю даты с января 2018 года, он принимает даты 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. Как это возможно?
1 ответ
Порядок вызываемых методов, кажется, имеет значение.
Если вы вызываете их по убыванию времени детализации (год, неделя недели и день недели), вы получите правильный результат:
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
) по текущему году.
Ява LocalDate
API не может адаптировать это значение, если вы измените год с .withYear(year)
так как информация о номере недели не хранится в LocalDate
пример.
Вы действительно можете увидеть в 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);
код возвращает ожидаемый результат. Кажется, как способ создания LocalDate имеет значение. Я предполагаю, что часовой пояс опущен в версии ".of()".