Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Period comparison functions #679

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/ical/period.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,24 @@ class Period {
}
}

/**
* Compare this period with a date or other period. To maintain the logic where a.compare(b)
* returns 1 when a > b, this function will return 1 when the period is after the date, 0 when the
* date is within the period, and -1 when the period is before the date. When comparing two
* periods, as soon as they overlap in any way this will return 0.
*
* @param {ICAL.Time|ICAL.Period} dt The date or other period to compare with
*/
compare(dt) {
if (dt.compare(this.start) < 0) {
return 1;
} else if (dt.compare(this.getEnd()) > 0) {
return -1;
} else {
return 0;
}
}

/**
* The string representation of this period.
* @return {String}
Expand Down
21 changes: 13 additions & 8 deletions lib/ical/time.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import Timezone from "./timezone.js";
import Duration from "./duration.js";
import Period from "./period.js";
import design from "./design.js";
import TimezoneService from "./timezone_service.js";
import { strictParseInt, trunc, pad2 } from "./helpers.js";
Expand Down Expand Up @@ -965,18 +966,22 @@ class Time {
}

/**
* Compares the ICAL.Time instance with another one.
* Compares the ICAL.Time instance with another one, or a period.
*
* @param {ICAL.Duration} aOther The instance to compare with
* @return {Number} -1, 0 or 1 for less/equal/greater
* @param {ICAL.Time|ICAL.Period} aOther The instance to compare with
* @return {Number} -1, 0 or 1 for less/equal/greater
*/
compare(other) {
let a = this.toUnixTime();
let b = other.toUnixTime();
if (other instanceof Period) {
return -1 * other.compare(this);
} else {
let a = this.toUnixTime();
let b = other.toUnixTime();

if (a > b) return 1;
if (b > a) return -1;
return 0;
if (a > b) return 1;
if (b > a) return -1;
return 0;
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions samples/recur_instances.ics
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ BEGIN:VEVENT
UID:623c13c0-6c2b-45d6-a12b-c33ad61c4868
DESCRIPTION:IAM FOO
RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU
RDATE:20231123T090000Z
RDATE;VALUE=PERIOD:20231125T090000Z/20231125T123000Z
SUMMARY:Crazy Event Thingy!
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Sahaja
Lal;X-NUM-GUESTS=0:mailto:calmozilla1@gmail.com
Expand Down
53 changes: 53 additions & 0 deletions test/period_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,4 +312,57 @@ suite('ical/period', function() {
assert.equal(subject1.duration, subject2.duration);
});
});

suite("#compare", function() {
test("with date", function() {
let subject = ICAL.Period.fromData({
start: ICAL.Time.fromString("1970-01-02T03:04:04Z"),
end: ICAL.Time.fromString("1970-01-02T03:04:06Z")
});

let beforestart = ICAL.Time.fromString("1970-01-02T03:04:03Z");
let between = ICAL.Time.fromString("1970-01-02T03:04:05Z");
let afterend = ICAL.Time.fromString("1970-01-02T03:04:07Z");

assert.equal(subject.compare(beforestart), 1);
assert.equal(subject.compare(subject.start), 0);
assert.equal(subject.compare(between), 0);
assert.equal(subject.compare(subject.end), 0);
assert.equal(subject.compare(afterend), -1);
});

test("with other period", function() {
let subject = ICAL.Period.fromData({
start: ICAL.Time.fromString("1970-01-02T03:04:04Z"),
end: ICAL.Time.fromString("1970-01-02T03:04:06Z")
});

let beforestart = ICAL.Period.fromData({
start: ICAL.Time.fromString("1970-01-02T03:04:02Z"),
end: ICAL.Time.fromString("1970-01-02T03:04:03Z")
});
let overlapstart = ICAL.Period.fromData({
start: ICAL.Time.fromString("1970-01-02T03:04:03Z"),
end: ICAL.Time.fromString("1970-01-02T03:04:05Z")
});
let within = ICAL.Period.fromData({
start: ICAL.Time.fromString("1970-01-02T03:04:05Z"),
end: ICAL.Time.fromString("1970-01-02T03:04:05Z")
});
let overlapend = ICAL.Period.fromData({
start: ICAL.Time.fromString("1970-01-02T03:04:05Z"),
end: ICAL.Time.fromString("1970-01-02T03:04:07Z")
});
let afterend = ICAL.Period.fromData({
start: ICAL.Time.fromString("1970-01-02T03:04:07Z"),
end: ICAL.Time.fromString("1970-01-02T03:04:09Z")
});

assert.equal(subject.compare(beforestart), 1);
assert.equal(subject.compare(overlapstart), 0);
assert.equal(subject.compare(within), 0);
assert.equal(subject.compare(overlapend), 0);
assert.equal(subject.compare(afterend), -1);
});
});
});
10 changes: 7 additions & 3 deletions test/recur_expansion_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,16 @@ suite('recur_expansion', function() {
let expected = [
new Date('2012-11-05T18:00:00.000Z'),
new Date('2012-11-10T18:00:00.000Z'),
new Date('2012-11-30T18:00:00.000Z')
];
new Date('2012-11-30T18:00:00.000Z'),

// RDATEs
new Date('2023-11-23T09:00:00.000Z'),
new Date('2023-11-25T09:00:00.000Z')
];

let dates = subject.ruleDates.map(function(time) {
return time.toJSDate();
// We have a period in here, take the start date
return (time.start || time).toJSDate();
});

assert.deepEqual(dates, expected);
Expand Down
21 changes: 21 additions & 0 deletions test/time_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1617,6 +1617,27 @@ suite('icaltime', function() {
assert.equal(a.compare(b), 1);
assert.equal(b.compare(a), -1);
});

test("compare with period", function() {
let periodbefore = ICAL.Period.fromData({
start: Time.fromString("1970-01-02T03:04:03Z"),
end: Time.fromString("1970-01-02T03:04:04Z")
});
let periodat = ICAL.Period.fromData({
start: Time.fromString("1970-01-02T03:04:05Z"),
end: Time.fromString("1970-01-02T03:04:05Z")
});
let periodafter = ICAL.Period.fromData({
start: Time.fromString("1970-01-02T03:04:06Z"),
end: Time.fromString("1970-01-02T03:04:07Z")
});

let dt = Time.fromString('1970-01-02T03:04:05Z');

assert.equal(dt.compare(periodbefore), 1);
assert.equal(dt.compare(periodat), 0);
assert.equal(dt.compare(periodafter), -1);
});
});

test('cache cleared', function() {
Expand Down