【问题标题】:How to make a date repeat every year for the last day of February in java for iCal google-rfc-2445java - 如何在Java中为iCal google-rfc-2445制作每年2月最后一天的日期重复
【发布时间】:2014-05-30 13:06:26
【问题描述】:

我需要在 2 月的最后一天重复一个日期,我正在使用 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

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

【问题讨论】:

  • 找到 3 月 1 日,然后减去 1 天是我这样做的方式。
  • 你真的需要一个带时间的日期还是一个简单的日期?如果是后者,永远不要使用 DateTime,使用 LocalDate。

标签: java jodatime icalendar rfc2445


【解决方案1】:

从 3 月 1 日减去一天。

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

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

【讨论】:

    【解决方案2】:

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

    "RRULE:FREQ=YEARLY;COUNT=6;INTERVAL=1;BYYEARDAY=-307"
    

    【讨论】:

      【解决方案3】:

      如果您只想操作日期,请不要使用 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;
      }
      

      【讨论】:

        【解决方案4】:

        如果您想确保收到一个月最后一天的事件,您应该使用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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多