0

我需要在二月的最后一天重复一个日期,我正在使用 Joda 时间来使用规则来生成几天、几周、几个月等的日期。因为 Months 工作正常,但是大约几年时我收到错误的输出。

private static List<DateTime> calculateRecurrentDates(DateTime startDate, String recurrentRule) {
    List<DateTime> dates = new ArrayList<DateTime>();
    TimeStamp startDate = Timestamp.valueOf("2011-02-28 10:10:10");
    String recurrentRule = "RRULE:FREQ=YEARLY;COUNT=6;INTERVAL=1;";
    String leapYearRule = "RRULE:FREQ=YEARLY;COUNT=6;INTERVAL=1;BYMONTHDAY=28,29;BYSETPOS=-1";

    try {
        DateTimeIterable range = DateTimeIteratorFactory.createDateTimeIterable(recurrentRule, startDate, DateTimeZone.UTC, true);
        for (DateTime date : range) {
           dates.add(date);
        }
    } catch (ParseException e) {
        dates = null;
        logger.error(e.getMessage());
    }
    return dates;
}

但我收到这个:

2011-02-28T10:10:10.000Z
2012-02-28T10:10:10.000Z
2013-02-28T10:10:10.000Z
2014-02-28T10:10:10.000Z
2015-02-28T10:10:10.000Z
2016-02-28T10:10:10.000Z

在闰年的情况下:

2012-02-29T10:10:10.000Z
2012-12-29T10:10:10.000Z
2013-12-29T10:10:10.000Z
2014-12-29T10:10:10.000Z
2015-12-29T10:10:10.000Z
2016-12-29T10:10:10.000Z 2017-12-29T10
:10:10.000Z

我如何编写一条规则来获得每年二月的最后一天?

4

4 回答 4

1

如果你想确保你在一个月的最后一天得到一个事件,你应该使用BYMONTHDAY=-1(参见RRULE in RFC),然后确保它只发生在二月BYMONTH=2,然后给出:

RRULE:FREQ=YEARLY;BYMONTH=2;BYMONTHDAY=-1

然后,由于您提到了一个COUNT属性,您还可以定义一个UNTIL指定直到您希望您RRULE被评估的时间:

RRULE:FREQ=YEARLY;BYMONTH=2;BYMONTHDAY=-1;UNTIL=20200302T070000Z
于 2014-04-18T12:21:27.717 回答
1

我的解决方案是从一年中的最后一天算到 3 月 1 日之前的一天。所以规则将是这样的:

"RRULE:FREQ=YEARLY;COUNT=6;INTERVAL=1;BYYEARDAY=-307"
于 2014-04-16T08:19:07.587 回答
0

从三月一日减去一天。

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime firstOfMarch = new DateTime( "2014-03-01", timeZone ).withTimeAtStartOfDay();
DateTime lastOfFebruary = firstOfMarch.minusDays( 1 ).withTimeAtStartOfDay();

firstOfMarch对象上,调用plusYears(1)以继续前进。

于 2014-04-16T06:30:38.260 回答
0

如果您只想操作日期,请不要使用 DateTimes,LocalDate 是正确的类。

如果你真的想得到二月的最后几天:

public static List<LocalDate> getLastDaysOfFebruary(LocalDate start, int n) {
    ArrayList<LocalDate> list = new ArrayList<>();
    LocalDate firstMar = start.withMonthOfYear(3).withDayOfMonth(1);
    if(! firstMar.isAfter(start)) firstMar = firstMar.plusYears(1);
    for(int i=0;i<n;i++) {
        list.add(firstMar.minusDays(1));
        firstMar = firstMar.plusYears(1);
    }
    return list;
}
于 2014-04-16T15:00:10.143 回答