【问题标题】:Joda Time: Calculate time to next full interval in monthJoda Time:计算一个月内下一个完整间隔的时间
【发布时间】:2021-04-08 10:03:25
【问题描述】:

我正在实现一个应用程序,用户可以在其中创建具有截止日期的任务并重复它们,例如每 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);
}

【问题讨论】:

    标签: java jodatime


    【解决方案1】:

    注意:Home Page of Joda-Time查看以下通知

    Joda-Time 是 Java 的事实上的标准日期和时间库 在 Java SE 8 之前。现在要求用户迁移到 java.time (JSR-310)。

    因此,我建议您使用java.time API 使用以下方法:

    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
    

    如您所见,除了createLocalDateTime 中的代码外,java.time 和 Joda-time API 的所有内容都是相同的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-15
      • 2011-10-14
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多