Как рассчитать месяц от общего количества дней разницы в иврите календарь - PullRequest
2 голосов
/ 01 октября 2019

Я использую это , чтобы вычислить разницу в количестве дней в еврейском календаре, и она возвращает правильную разницу дней. Теперь я хочу перевести эти дни в месяцы или годы.

Но проблема в еврейском календаре

Год в еврейском календаре может быть 353, 354, 355,383, 384 или 385 дней. Обычные обычные годы имеют 12 месяцев, в общей сложности 354 дня. Високосные годы имеют 13 месяцев и 384 дня. Месяцы с нечетными числами обычно имеют 30 дней, а месяцы с четными числами - 29 дней.

Я пытался разделить дни на общее количество дней в году, но общее количество дней вгод. Можете ли вы порадовать меня идеей, как этого добиться?

Ответы [ 2 ]

0 голосов
/ 11 октября 2019

Вы можете использовать мою библиотеку lib Time4J , которая предлагает функцию определения различий, измеряемых в годах, месяцах или днях. Пример (из тестового примера JUnit):

    HebrewCalendar start = HebrewCalendar.of(5778, HebrewMonth.HESHVAN, 6);
    HebrewCalendar end = HebrewCalendar.of(5778, HebrewMonth.ELUL, 6);

    assertThat(HebrewCalendar.Unit.MONTHS.between(start, end), is(10));

    start = start.plus(CalendarDays.ONE);
    assertThat(HebrewCalendar.Unit.MONTHS.between(start, end), is(9));

    start = start.minus(3, HebrewCalendar.Unit.YEARS);
    assertThat(HebrewCalendar.Unit.YEARS.between(start, end), is(3));

    start = start.plus(6, HebrewCalendar.Unit.YEARS).minus(CalendarDays.of(2)); // AM-5781-HESHVAN-5
    assertThat(HebrewCalendar.Unit.YEARS.between(start, end), is(-2));

    start = start.with(HebrewCalendar.MONTH_OF_YEAR, HebrewMonth.ELUL); // AM-5781-ELUL-5
    assertThat(HebrewCalendar.Unit.MONTHS.between(start, end), is(-36));

    start = start.plus(CalendarDays.ONE);
    assertThat(HebrewCalendar.Unit.MONTHS.between(start, end), is(-37));

    start = start.minus(37, HebrewCalendar.Unit.MONTHS);
    assertThat(start, is(end));

Логика чем-то похожа на стандартную логику в java.time -пакете. Если день окончания месяца меньше даты начала, вычисленная дельта месяца (или года) уменьшается на единицу.

Как правило, я не рекомендую пытаться преобразовать дни вмесяцы или годы с применением фиксированного фактора, потому что еврейский календарь имеет иногда 12, иногда 13 месяцев. Моя библиотека тоже не пробует, но применяет оптимизированный вид подсчета. Также невозможно преобразовать дельту дня в дельту месяца без какой-либо дополнительной информации о дате начала или окончания по основным причинам:

Imagine the SAME day delta had been determined with a start date 
short before Adar I (leap month) or with another month later. Then the month
delta will be different because the second case does not include a leap month!

Дополнительные примеры того, как обращаться с еврейским календарем, могутбыть замеченным в API онлайн .

Если вы работаете на Android, используйте специализированный производный Time4A с аналогичным API.

0 голосов
/ 01 октября 2019

Похоже, цикл, который продолжает вычитать, проще всего понять. Я думаю, вы знаете год с обеих сторон. Тогда такой цикл может сработать:

int yearBegin = 1234;
int daysDiff = calcDaysDiff(); // your existing routine
int yearAnalyzing = yearBegin;
int years = 0;
while (daysDiff > 0) {
    int daysInThatYear = calcDaysInYear (yearAnalyzing); // you calc accdg your rules
    while (daysDiff >= daysInThatYear) {
        ++years;
        daysDiff -= daysinThatYear;
        yearAnalyzing++; // or --, depending which direction you want to go
    }
    // less than a year is left
    // calculate the months (should be easy)
}

Если ваша начальная дата начинается в середине года, вам придется сначала работать в эти выходные, прежде чем вы начнете цикл.

...