Noda Time: Period.Between() возвращает неправильное количество дней?

Учитывая приведенный ниже фрагмент кода, почему последние четыре периода вывода одинаковы? Я ожидаю, что часть дней для этих строк будет 4, 3, 2, 1, а не 4, 4, 4, 4. Это ошибка или я упускаю что-то очевидное? (Уже поздно и я устал, так что, скорее всего, последнее.) Я использую Noda Time 1.2.0.

for (int day = 25; day <= 31; day++)
{
    var d1 = new LocalDate(2013, 12, day);
    var d2 = new LocalDate(2015, 3, 4);

    var period = Period.Between(d1, d2);
    Debug.WriteLine("Day: {0}, Period: {1}", day, period);
}

// I get the following output:
Day: 25, Period: P1Y2M7D
Day: 26, Period: P1Y2M6D
Day: 27, Period: P1Y2M5D
Day: 28, Period: P1Y2M4D
Day: 29, Period: P1Y2M4D
Day: 30, Period: P1Y2M4D
Day: 31, Period: P1Y2M4D

person Nick Spreitzer    schedule 31.12.2013    source источник
comment
Я предполагаю, что проблема находится в методе Period.Between   -  person Tony    schedule 31.12.2013
comment
Если я что-то не упустил, то да, я так думаю.   -  person Nick Spreitzer    schedule 31.12.2013
comment
Моей первой мыслью было, может быть, это как-то связано с тем, что в месяце не было 31 дня, может быть, он считал 28-31 одним и тем же днем. Это могло быть проблемой для февраля, но, учитывая, что вы используете декабрь, я сомневаюсь, что это проблема.   -  person Steven Mills    schedule 31.12.2013
comment
В вашей местности бывает 28 дней в 12-м месяце года? Возможно, по негригорианскому календарю.   -  person Servy    schedule 01.01.2014
comment
@Servy: Хороший вопрос, но нет. Я использую календарную систему по умолчанию, в которой 31 день в 12-м месяце.   -  person Nick Spreitzer    schedule 01.01.2014
comment
Ради интереса, теперь, когда вы прочитали документы, считаете ли вы это недостатком в Noda Time или просто неотъемлемым раздражителем из-за переменной длины месяца? Я очень открыт для предложений о лучших способах выполнения арифметики даты/времени.   -  person Jon Skeet    schedule 01.01.2014
comment
@JonSkeet: Последнее. Чем больше я думал об этом, тем больше смысла имели результаты, которые я опубликовал в своем вопросе. Если есть лучший способ, я не могу придумать, что бы это было.   -  person Nick Spreitzer    schedule 02.01.2014
comment
@Ник: Верно. Не знаю, радует меня это или огорчает...   -  person Jon Skeet    schedule 02.01.2014


Ответы (1)


Это связано с тем, как выполняется расчет периода - из Арифметика даты и времени в Noda Time: "правило очень простое: добавляется по одному компоненту за раз, начиная с наиболее значимого, и оборачивая/усекая на каждом шагу."

Поэтому, когда он проходит в феврале, происходит усечение до 28 дней. Вы можете увидеть, что то же самое происходит с усечением до 30 дней, если вы отредактируете свой код, чтобы перейти от (2013, 3, day) к (2013, 5, 4):

Day: 25, Period: P1M9D
Day: 26, Period: P1M8D
Day: 27, Period: P1M7D
Day: 28, Period: P1M6D
Day: 29, Period: P1M5D
Day: 30, Period: P1M4D
Day: 31, Period: P1M4D

Если вы получите период только в днях (Period.Between(d1, d2, PeriodUnits.Days)), вы получите ожидаемое число по убыванию:

Day: 25, Period: P434D
Day: 26, Period: P433D
Day: 27, Period: P432D
Day: 28, Period: P431D
Day: 29, Period: P430D
Day: 30, Period: P429D
Day: 31, Period: P428D
person Andrew Morton    schedule 31.12.2013
comment
Спасибо. Думаю, мне следовало более внимательно прочитать документацию. - person Nick Spreitzer; 01.01.2014
comment
Хороший ответ! Но, пожалуйста, в следующий раз дайте ссылку на новый сайт nodatime.org. Я обновил этот. - person Matt Johnson-Pint; 02.01.2014
comment
@MattJohnson Спасибо за обновление. Я получил информацию через Google, и он не представил мне nodatime.org. Однако он появляется в результатах поиска сегодня. - person Andrew Morton; 02.01.2014
comment
Без проблем. И счастливого нового года! - person Matt Johnson-Pint; 02.01.2014