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

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

AlarmHelper.java

// Works
static LocalDateTime getNextWeeklyIntervalDate(LocalDateTime creationTime, LocalDateTime dueTime, int intervalInWeeks) {
    int intervalInMinutes = Weeks.weeks(intervalInWeeks).toStandardMinutes().getMinutes();
    int timePassed = Minutes.minutesBetween(creationTime, dueTime).getMinutes();
    int rest = timePassed % intervalInMinutes;
    int minutesToNextFullInterval = intervalInMinutes - rest;
    return dueTime.plusMinutes(minutesToNextFullInterval );
}

// How to implement this analogous to weekly, but for monthly intervals? toStandardMinutes() does not exist for months  
static LocalDateTime getNextMonthlyIntervalDate(LocalDateTime creationTime, LocalDateTime dueTime, int intervalInMonth) {
    int intervalInMinutes = Months.months(intervalInMonth).toStandardMinutes().getMinutes(); // toStandardMinutes() does not exist
}

AlarmHelperTest.java

// User created the task on 01.01.2021 (January 1st, 2021) and want to repeat it weekly.
// So the intervals are 08.01.2021, 15.01.2021 etc.
// In the test the task is due on 12.01.2021, which means the next weekly interval is fulfilled on 15.01.2021.

//The test passes
 @Test
 public void TestGetNextWeeklyIntervalDate() {
    LocalDateTime creation = createLocalDateTime("01.01.2021 06:30:00");
    LocalDateTime due = createLocalDateTime("12.01.2021 05:30:00");
    LocalDateTime expected = createLocalDateTime("15.01.2021 06:30:00");
    LocalDateTime result = AlarmHelper.getNextWeeklyIntervalDate(creation, due, 1);
    assertEquals(expected, result);
}

Kewitschka

Ответов: 1

Ответы (1)

Примечание: Проверьте следующее примечание на домашней странице Joda-Time

Joda-Time is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to java.time (JSR-310).

Поэтому я рекомендую вам сделать это с помощью API java.time, используя следующие методы:

  1. LocalDateTime # isBefore
  2. LocalDateTime # plusWeeks
  3. LocalDateTime # plusMonths

Использование java.time API:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDateTime creation = createLocalDateTime("01.01.2021 06:30:00");
        LocalDateTime due = createLocalDateTime("12.01.2021 05:30:00");
        System.out.println(getNextWeeklyIntervalDate(creation, due, 1));
        System.out.println(getNextMonthlyIntervalDate(creation, due, 1));
    }

    static LocalDateTime getNextWeeklyIntervalDate(LocalDateTime creationTime, LocalDateTime dueTime,
            int intervalInWeeks) {
        LocalDateTime ldt = creationTime;
        while (ldt.isBefore(dueTime)) {
            ldt = ldt.plusWeeks(intervalInWeeks);
        }
        return ldt;
    }

    static LocalDateTime getNextMonthlyIntervalDate(LocalDateTime creationTime, LocalDateTime dueTime,
            int intervalInMonth) {
        LocalDateTime ldt = creationTime;
        while (ldt.isBefore(dueTime)) {
            ldt = ldt.plusMonths(intervalInMonth);
        }
        return ldt;
    }

    static LocalDateTime createLocalDateTime(String dateTimeStr) {
        return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss", Locale.ENGLISH));
    }
}

Вывод:

2021-01-15T06:30
2021-02-01T06:30

Эти методы также доступны в Joda-time API, т.е. все, что вам нужно изменить, это способ анализа строки даты и времени и получения LocalDateTime.

Использование Joda-time API:

import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        LocalDateTime creation = createLocalDateTime("01.01.2021 06:30:00");
        LocalDateTime due = createLocalDateTime("12.01.2021 05:30:00");
        System.out.println(getNextWeeklyIntervalDate(creation, due, 1));
        System.out.println(getNextMonthlyIntervalDate(creation, due, 1));
    }

    static LocalDateTime getNextWeeklyIntervalDate(LocalDateTime creationTime, LocalDateTime dueTime,
            int intervalInWeeks) {
        LocalDateTime ldt = creationTime;
        while (ldt.isBefore(dueTime)) {
            ldt = ldt.plusWeeks(intervalInWeeks);
        }
        return ldt;
    }

    static LocalDateTime getNextMonthlyIntervalDate(LocalDateTime creationTime, LocalDateTime dueTime,
            int intervalInMonth) {
        LocalDateTime ldt = creationTime;
        while (ldt.isBefore(dueTime)) {
            ldt = ldt.plusMonths(intervalInMonth);
        }
        return ldt;
    }

    static LocalDateTime createLocalDateTime(String dateTimeStr) {
        DateTimeFormatter dtf = DateTimeFormat.forPattern("dd.MM.yyyy HH:mm:ss");
        LocalDateTime ldt = dtf.parseDateTime(dateTimeStr).toLocalDateTime();
        return ldt;
    }
}

Вывод:

2021-01-15T06:30:00.000
2021-02-01T06:30:00.000

As you can see, every thing, except the code inside createLocalDateTime, is same for both java.time and Joda-time API.

2022 WebDevInsider