簡體   English   中英

如何用Java解析iCal RRULE

[英]How to parse an iCal RRULE in Java

我有以下iCal重復規則示例:

"RRULE:FREQ=YEARLY;INTERVAL=2"
"RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,TH"

我需要一個Java庫來解析RRULE模式以處理對象。 有沒有好的Java庫?


你可以使用lib-recur

它仍然受支持並處理RFC 5545和RFC 2445。

RecurrenceRule rule = new RecurrenceRule("FREQ=YEARLY;BYMONTHDAY=23;BYMONTH=5");

DateTime start = new DateTime(1982, 4 /* 0-based month numbers! */,23);

RecurrenceRuleIterator it = rule.iterator(start);

int maxInstances = 100; // limit instances for rules that recur forever

while (it.hasNext() && (!rule.isInfinite() || maxInstances-- > 0))
{
    DateTime nextInstance = it.nextDateTime();
    // do something with nextInstance
}

你可以用maven安裝它

<!-- https://mvnrepository.com/artifact/org.dmfs/lib-recur -->
<dependency>
    <groupId>org.dmfs</groupId>
    <artifactId>lib-recur</artifactId>
     <version>0.10.2</version>
</dependency>

或者用gradle

// https://mvnrepository.com/artifact/org.dmfs/lib-recur 
compile group: 'org.dmfs', name: 'lib-recur', version: '0.10.2'

這里有更多文檔: https//github.com/dmfs/lib-recur

解決方案是使用

        <dependency>
            <groupId>org.scala-saddle</groupId>
            <artifactId>google-rfc-2445</artifactId>
            <version>20110304</version>
        </dependency>

幾個例子:

1轉換為java對象:

rule = new RRule("RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,TH");

2轉回:

rule.toIcal();

這是我用https://github.com/mangstadt/biweekly庫生成幾個(dateStart - dateEnd)的方法。

收益是: - 開始日期 - 結束日期(facultatif) - RRULE,由|分隔

DTSTART:2019-07-01T16:00:00Z|DTEND:2019-07-01T17:00:00Z|RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA,SU;UNTIL=2019-07-31T23:59:59Z

碼:

// A.  split filter $iCalFilter
Map<String, String> iCalFilterMap = new HashMap<>();
for (String part : iCalFilter.split("\\|")) {
    if (part.contains(":")) {
        String[] subparts = part.split(":", 2);
        iCalFilterMap.put(subparts[0], subparts[1]);
    }
}

// B. generate couples of dates starts and  dates ends
ParseContext context = new ParseContext();
context.setVersion(ICalVersion.V2_0);
RecurrenceRuleScribe scribe = new RecurrenceRuleScribe();
RecurrenceRule rrule = scribe.parseText(iCalFilterMap.get(iCalFilterConstant.RRULE), ICalDataType.DATE_TIME, new ICalParameters(), context);
TimeZone timezone = TimeZone.getTimeZone(iCalFilterConstant.UTC);
int iCalFilterMaximumDayToGenerate = 365;

        // DTSTART && DTEND
        List<DateTime> listeDateStart = new ArrayList<>();
        List<DateTime> listeDateEnd = new ArrayList<>();

        if (null != inCalendarMap.get(InCalendarConstant.DTSTART)) {
            DateTime dateTimeStart = new DateTime(inCalendarMap.get(InCalendarConstant.DTSTART)).withZone(InCalendarConstant.DATE_TIME_ZONE_UTC);

            DateTime dateTimeEnd;
            if (null != inCalendarMap.get(InCalendarConstant.DTEND)) {
                dateTimeEnd = new DateTime(inCalendarMap.get(InCalendarConstant.DTEND)).withZone(InCalendarConstant.DATE_TIME_ZONE_UTC);
            } else {
                // Si le DTEND n'est pas renseigné par le client, alors on le met par défaut en fin de journée
                dateTimeEnd = new DateTime(inCalendarMap.get(InCalendarConstant.DTSTART)).withZone(InCalendarConstant.DATE_TIME_ZONE_UTC).withTime(23, 59, 59, 999);
            }

            Interval interval = new Interval(dateTimeStart, dateTimeEnd);

            DateIterator ditStart = rrule.getDateIterator(dateTimeStart.toDate(), timezone);
            int compteurDateStart = 0;
            while (ditStart.hasNext()) {
                DateTime dateStart = new DateTime(ditStart.next()).withZone(InCalendarConstant.DATE_TIME_ZONE_UTC);
                listeDateStart.add(dateStart);

                DateTime dateEnd = dateStart.plus(interval.toDurationMillis());
                listeDateEnd.add(new DateTime(dateEnd).withZone(InCalendarConstant.DATE_TIME_ZONE_UTC));
                logger.logDebug(dateStart + "---" + dateEnd);

                // Pour éviter une boucle infinie, ou une date de génération en 9999-12-12T23:59:59 , on limite le nombre de jours
                compteurDateStart++;
                if(compteurDateStart > inCalendarMaximumDayToGenerate) {
                    break;
                }
            }
        }

        // C. on set le couple dans le filters LesHalles pour utilisation dans la requete bdd voir CourseJdbcDaoImpl.addInCalendar
        if(listeDateStart.size() == 0 || listeDateEnd.size() == 0) {
            throw new ServiceFunctionalException(new Object[] { inCalendar  }, MessageFonctionnelTheorique.IN_CALENDAR_RRULE_AUCUNE_DATE_GENEREE);
        }
        ImmutablePair<List<DateTime>, List<DateTime>> pairListeDatesStartsDatesEnds = new ImmutablePair<>(listeDateStart, listeDateEnd);
        filters.setInCalendarDateStartDateEnds(pairListeDatesStartsDatesEnds);
    }

您現在可以使用這幾個datestart dateends進行數據庫查詢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM