Joda Time:计算下一个完整间隔的时间
Joda Time: Calculate time to next full interval in month
我正在实现一个应用程序,用户可以在其中创建具有截止日期的任务并重复它们,例如每 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);
}
查看以下通知
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).
因此,我建议您使用以下方法与 java.time
API 一起使用:
使用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.
中的所有内容都是相同的
我正在实现一个应用程序,用户可以在其中创建具有截止日期的任务并重复它们,例如每 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);
}
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).
因此,我建议您使用以下方法与 java.time
API 一起使用:
使用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.