diff --git a/autotests/testtimesininterval.h b/autotests/testtimesininterval.h --- a/autotests/testtimesininterval.h +++ b/autotests/testtimesininterval.h @@ -33,6 +33,8 @@ void testSubDailyRecurrenceIntervalInclusive(); void testSubDailyRecurrence2(); void testSubDailyRecurrenceIntervalLimits(); + void testLocalTimeHandlingNonAllDay(); + void testLocalTimeHandlingAllDay(); }; #endif diff --git a/autotests/testtimesininterval.cpp b/autotests/testtimesininterval.cpp --- a/autotests/testtimesininterval.cpp +++ b/autotests/testtimesininterval.cpp @@ -155,3 +155,103 @@ } QCOMPARE(expectedEventOccurrences.size(), 0); } + +void TimesInIntervalTest::testLocalTimeHandlingNonAllDay() +{ + // Create an event which occurs every weekday of every week, + // starting from Friday the 11th of October, from 12 pm until 1 pm, clock time, + // and lasts for two weeks, with three exception datetimes, + // (only two of which will apply). + QTimeZone anotherZone(QTimeZone::systemTimeZoneId().contains("Toronto") + ? QTimeZone(QByteArray("Pacific/Midway")) + : QTimeZone(QByteArray("America/Toronto"))); + Event event; + event.setAllDay(false); + event.setDtStart(QDateTime(QDate(2019, 10, 11), QTime(12, 0), Qt::LocalTime)); + + RecurrenceRule * const rule = new RecurrenceRule(); + rule->setRecurrenceType(RecurrenceRule::rDaily); + rule->setStartDt(event.dtStart()); + rule->setFrequency(1); + rule->setDuration(14); + rule->setByDays(QList() + << RecurrenceRule::WDayPos(0, 1) // Monday + << RecurrenceRule::WDayPos(0, 2) // Tuesday + << RecurrenceRule::WDayPos(0, 3) // Wednesday + << RecurrenceRule::WDayPos(0, 4) // Thursday + << RecurrenceRule::WDayPos(0, 5)); // Friday + + Recurrence *recurrence = event.recurrence(); + recurrence->addRRule(rule); + // 12 o'clock in local time, will apply. + recurrence->addExDateTime(QDateTime(QDate(2019, 10, 15), QTime(12, 0), + Qt::LocalTime)); + // 12 o'clock in another time zone, will not apply. + recurrence->addExDateTime(QDateTime(QDate(2019, 10, 17), QTime(12, 0), + anotherZone)); + // The time in another time zone, corresponding to 12 o'clock in the system time zone, will apply. + recurrence->addExDateTime(QDateTime(QDate(2019, 10, 24), QTime(12, 00), + QTimeZone::systemTimeZone()).toTimeZone(anotherZone)); + + // Expand the events and within a wide interval + const DateTimeList timesInInterval = + recurrence->timesInInterval(QDateTime(QDate(2019, 10, 05), QTime(0, 0)), + QDateTime(QDate(2019, 10, 25), QTime(23, 59))); + + // ensure that the expansion does not include weekend days, + // nor either of the exception date times. + const QList expectedDays { 11, 14, 16, 17, 18, 21, 22, 23, 25 }; + for (int day : expectedDays) { + QVERIFY(timesInInterval.contains(QDateTime(QDate(2019, 10, day), QTime(12, 0), Qt::LocalTime))); + } + QCOMPARE(timesInInterval.size(), expectedDays.size()); +} + +void TimesInIntervalTest::testLocalTimeHandlingAllDay() +{ + // Create an event which occurs every weekday of every week, + // starting from Friday the 11th of October, and lasts for two weeks, + // with four exception datetimes (only three of which will apply). + QTimeZone anotherZone(QTimeZone::systemTimeZoneId().contains("Toronto") + ? QTimeZone(QByteArray("Pacific/Midway")) + : QTimeZone(QByteArray("America/Toronto"))); + Event event; + event.setAllDay(true); + event.setDtStart(QDateTime(QDate(2019, 10, 11))); + + RecurrenceRule * const rule = new RecurrenceRule(); + rule->setRecurrenceType(RecurrenceRule::rDaily); + rule->setStartDt(event.dtStart()); + rule->setFrequency(1); + rule->setDuration(14); + rule->setByDays(QList() + << RecurrenceRule::WDayPos(0, 1) // Monday + << RecurrenceRule::WDayPos(0, 2) // Tuesday + << RecurrenceRule::WDayPos(0, 3) // Wednesday + << RecurrenceRule::WDayPos(0, 4) // Thursday + << RecurrenceRule::WDayPos(0, 5)); // Friday + + Recurrence *recurrence = event.recurrence(); + recurrence->addRRule(rule); + // A simple date, will apply. + recurrence->addExDate(QDate(2019, 10, 14)); + // A date only local time, will apply. + recurrence->addExDateTime(QDateTime(QDate(2019, 10, 15))); + // A date time starting at 00:00 in another zone, will not apply. + recurrence->addExDateTime(QDateTime(QDate(2019, 10, 17), QTime(), anotherZone)); + // A date time starting at 00:00 in the system time zone, will apply. + recurrence->addExDateTime(QDateTime(QDate(2019, 10, 24), QTime(), QTimeZone::systemTimeZone())); + + // Expand the events and within a wide interval + const DateTimeList timesInInterval = + recurrence->timesInInterval(QDateTime(QDate(2019, 10, 05), QTime(0, 0)), + QDateTime(QDate(2019, 10, 25), QTime(23, 59))); + + // ensure that the expansion does not include weekend days, + // nor either of the exception date times. + const QList expectedDays { 11, 16, 17, 18, 21, 22, 23, 25 }; + for (int day : expectedDays) { + QVERIFY(timesInInterval.contains(QDateTime(QDate(2019, 10, day)))); + } + QCOMPARE(timesInInterval.size(), expectedDays.size()); +}