Ответ 1
Joda-Time правильная, но не ваша логика. Вы должны тщательно различать "календарный год" (начиная с первого января) и год недели (как определено в ISO-8601, также называемый "недельный год" или просто "неделя" -YEAR ").
Например, вы используете в своем классе два члена, которые не строго коррелируют друг с другом для хранения промежуточных результатов:
week = nextWeek.getWeekOfWeekyear();
year = nextWeek.getYear();
Проблема с этими строками заключается в том, что неделя связана с недельным годом, а не с календарным годом, как показывает вторая строка. Имейте в виду, что недельный год может быть на один год меньше календарного года с первого января. Например, [2014-12-31] - это тот же день, что и [2015-W01-3]. Имейте в виду, что Joda-Time предлагает другой метод под названием getWeekyear()
.
Затем вы будете использовать эти два значения для управления датой следующим образом:
LocalDate today = new LocalDate()
.withDayOfWeek(4)
.withWeekOfWeekyear(week)
.withYear(year);
Снова та же проблема терминологии. И метод withWeekOfWeekyear(week)
может уже изменить календарный год и сменить день месяца на другой день при попытке сохранить день недели в течение текущего недельного года 2015, а не календарный год 2014, производя неожиданный сдвиг даты! Весь код дает результаты, которые на самом деле не предсказуемы и удивят всех. Еще одна большая проблема - это порядок вызовов методов, что имеет значение, потому что манипуляция с неделями относится к текущему недельному году (какой?!). Следующий код выглядел бы намного здоровее:
LocalDate today = new LocalDate()
.withWeekyear(year)
.withWeekOfWeekyear(week)
.withDayOfWeek(4);
Решение:. Вам следует лучше ссылаться на недельный год, а не на календарный год в вашем коде. Или даже лучше: если вы просто хотите добавить или удалить недели, я предлагаю вам сохранить дату (как объект типа LocalDate
) и применить date.plusWeeks(1)
или аналогичный. Вы всегда можете запросить дату дня недели, недели недели, год, год, календарный год и т.д. Гораздо лучше, чем экономить неделю-год и календарный год.
Обновление после тестирования:
Теперь я изменил год на неделю, а также изменил порядок вызовов методов при настройке даты (сначала недельный, затем неделю и, наконец, день недели). После этих изменений ваш код будет работать нормально в соответствии с моими собственными тестами (хотя я по-прежнему рекомендую вам упростить состояние и логику вашего класса). Здесь мой полный измененный и исправленный код:
import org.joda.time.LocalDate;
public class WonkyWeeks {
int year;
int week;
public void backUpOneWeek() {
LocalDate today =
new LocalDate().withWeekyear(year).withWeekOfWeekyear(week).withDayOfWeek(4);
LocalDate adayago = today.minusDays(1);
System.out.println(adayago + " - removed one day");
LocalDate twodaysago = adayago.minusDays(1);
System.out.println(twodaysago + " - removed one day");
LocalDate threedaysago = twodaysago.minusDays(1);
System.out.println(threedaysago + " - removed one day");
LocalDate fourdaysago = threedaysago.minusDays(1);
System.out.println(fourdaysago + " - removed one day");
LocalDate fivedaysago = fourdaysago.minusDays(1);
System.out.println(fivedaysago + " - removed one day");
LocalDate sixdaysago = fivedaysago.minusDays(1);
System.out.println(sixdaysago + " - removed one day");
LocalDate lastWeek = sixdaysago.minusDays(1);
week = lastWeek.getWeekOfWeekyear();
year = lastWeek.getWeekyear();
System.out.println(lastWeek + " - Removed one full week");
}
public void forwardOneWeek() {
LocalDate today =
new LocalDate().withWeekyear(year).withWeekOfWeekyear(week).withDayOfWeek(4);
LocalDate tomorrow = today.plusDays(1);
System.out.println(tomorrow + " - added one day");
LocalDate dayAfterTomorrow = tomorrow.plusDays(1);
System.out.println(dayAfterTomorrow + " - added one day");
LocalDate threeDaysFromNow = dayAfterTomorrow.plusDays(1);
System.out.println(threeDaysFromNow + " - added one day");
LocalDate fourDaysFromNow = threeDaysFromNow.plusDays(1);
System.out.println(fourDaysFromNow + " - added one day");
LocalDate fiveDaysFromNow = fourDaysFromNow.plusDays(1);
System.out.println(fiveDaysFromNow + " - added one day");
LocalDate sixDaysFromNow = fiveDaysFromNow.plusDays(1);
System.out.println(sixDaysFromNow + " - added one day");
LocalDate nextWeek = sixDaysFromNow.plusDays(1);
week = nextWeek.getWeekOfWeekyear();
year = nextWeek.getWeekyear();
System.out.println(nextWeek + " - Added one week");
}
public void thisWeek() {
LocalDate thisWeek =
new LocalDate().withWeekyear(year).withWeekOfWeekyear(week).withDayOfWeek(4);
System.out.println(thisWeek + " - This is the current week");
}
public static void main(String[] args) {
WonkyWeeks wonky = new WonkyWeeks();
wonky.week = 2;
wonky.year = 2015;
wonky.thisWeek();
wonky.backUpOneWeek();
wonky.backUpOneWeek();
wonky.backUpOneWeek();
wonky.backUpOneWeek();
wonky.forwardOneWeek();
wonky.forwardOneWeek();
wonky.forwardOneWeek();
wonky.forwardOneWeek();
}
}
Вывод измененного кода:
2015-01-08 - This is the current week
2015-01-07 - removed one day
2015-01-06 - removed one day
2015-01-05 - removed one day
2015-01-04 - removed one day
2015-01-03 - removed one day
2015-01-02 - removed one day
2015-01-01 - Removed one full week
2014-12-31 - removed one day
2014-12-30 - removed one day
2014-12-29 - removed one day
2014-12-28 - removed one day
2014-12-27 - removed one day
2014-12-26 - removed one day
2014-12-25 - Removed one full week
2014-12-24 - removed one day
2014-12-23 - removed one day
2014-12-22 - removed one day
2014-12-21 - removed one day
2014-12-20 - removed one day
2014-12-19 - removed one day
2014-12-18 - Removed one full week
2014-12-17 - removed one day
2014-12-16 - removed one day
2014-12-15 - removed one day
2014-12-14 - removed one day
2014-12-13 - removed one day
2014-12-12 - removed one day
2014-12-11 - Removed one full week
2014-12-12 - added one day
2014-12-13 - added one day
2014-12-14 - added one day
2014-12-15 - added one day
2014-12-16 - added one day
2014-12-17 - added one day
2014-12-18 - Added one week
2014-12-19 - added one day
2014-12-20 - added one day
2014-12-21 - added one day
2014-12-22 - added one day
2014-12-23 - added one day
2014-12-24 - added one day
2014-12-25 - Added one week
2014-12-26 - added one day
2014-12-27 - added one day
2014-12-28 - added one day
2014-12-29 - added one day
2014-12-30 - added one day
2014-12-31 - added one day
2015-01-01 - Added one week
2015-01-02 - added one day
2015-01-03 - added one day
2015-01-04 - added one day
2015-01-05 - added one day
2015-01-06 - added one day
2015-01-07 - added one day
2015-01-08 - Added one week