Skip to content

Commit

Permalink
tz offset, include missing recurring events
Browse files Browse the repository at this point in the history
  • Loading branch information
muness committed Jul 25, 2023
1 parent 3140306 commit c8d52a5
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 45 deletions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@ This only works with the Daily Note or [Periodic Notes](https://github.com/liamc

## Development state

Alas, work limits us to only a couple of apps for note taking and Obsidian isn't on the approved list. :/ As such I don't get to use it nor this plugin much.

It mostly works though I've seen it occasionally [miss some recurring events](https://github.com/muness/obsidian-ics/issues/36) and someone has reported a [timezone issue](https://github.com/muness/obsidian-ics/issues/37) though I haven't seen it. Give that I don't use it often, it's unlikely that I'll get to fix these issues.

I welcome a fork and will update this README to point to it if someone wants to take over.
The plugin mostly works though I've seen it occasionally [miss some recurring events](https://github.com/muness/obsidian-ics/issues/36). Once I fix those I'll submit it to the Obsidian Community plugin marketplace. PRs and other help welcome!

## Installation

Manual Installation
1. Download the latest `obsidian-ics-[version].zip` file from [releases](https://github.com/muness/obsidian-ics/releases).

1. Download the latest `obsidian-ics.zip` file from [releases](https://github.com/muness/obsidian-ics/releases).
2. Unpack the file. It should create a `obsidian-ics` folder.
3. Place the folder in your .obsidian/plugins directory
4. Reload plugins
Expand Down
56 changes: 17 additions & 39 deletions src/icalUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ function findRecurringEvents(icsArray: any[], dayToMatch: string) {

const rangeStart = moment(dayToMatch);
const rangeEnd = moment(dayToMatch).add(1439, 'minutes');
// console.log(rangeStart.format(), rangeEnd.format());
for (const k in icsArray) {
const event = icsArray[k];
const title = event.summary;
Expand All @@ -29,17 +28,6 @@ function findRecurringEvents(icsArray: any[], dayToMatch: string) {
let startDate = moment(event.start);
let endDate = moment(event.end);

// record if event was created in different DST status than now
let dstChange = 0;

if(startDate.isDST() && !moment().isDST()){
dstChange = 1;
}

if(!startDate.isDST() && moment().isDST()){
dstChange = -1;
}

// Calculate the duration of the event for use with recurring events.
const duration = Number.parseInt(endDate.format('x'), 10) - Number.parseInt(startDate.format('x'), 10);

Expand All @@ -51,21 +39,6 @@ function findRecurringEvents(icsArray: any[], dayToMatch: string) {
return true;
});

// The "dates" array contains the set of dates within our desired date range range that are valid
// for the recurrence rule. *However*, it's possible for us to have a specific recurrence that
// had its date changed from outside the range to inside the range. One way to handle this is
// to add *all* recurrence override entries into the set of dates that we check, and then later
// filter out any recurrences that don't actually belong within our range.
if (event.recurrences !== undefined) {
for (const r in event.recurrences) {
// Only add dates that weren't already in the range we added from the rrule so that
// we don't double-add those events.
if (moment(new Date(r)).isBetween(rangeStart, rangeEnd) !== true) {
dates.push(new Date(r));
}
}
}

// Loop through the set of date entries to see which recurrences should be included.
for (const i in dates) {
const date = dates[i];
Expand All @@ -78,35 +51,40 @@ function findRecurringEvents(icsArray: any[], dayToMatch: string) {
// Use just the date of the recurrence to look up overrides and exceptions (i.e. chop off time information)
const dateLookupKey = date.toISOString().slice(0, 10);

let overriden = '';
// For each date that we're checking, it's possible that there is a recurrence override for that one day.
if (curEvent.recurrences !== undefined && curEvent.recurrences[dateLookupKey] !== undefined) {
// We found an override, so for this recurrence, use a potentially different title, start date, and duration.
curEvent = curEvent.recurrences[dateLookupKey];
startDate = moment(curEvent.start);
curDuration = Number.parseInt(moment(curEvent.end).format('x'), 10) - Number.parseInt(startDate.format('x'), 10);
overriden = 'overridden ';
} else if (curEvent.exdate !== undefined && curEvent.exdate[dateLookupKey] !== undefined) {
// If there's no recurrence override, check for an exception date. Exception dates represent exceptions to the rule.
// This date is an exception date, which means we should skip it in the recurrence pattern.
includeRecurrence = false;
}

// Set the the end date from the regular event or the recurrence override.
let endDate = moment(Number.parseInt(startDate.format('x'), 10) + curDuration, 'x');

// If this recurrence ends before the start of the date range, or starts after the end of the date range,
// don't process it.
if (endDate.isBefore(rangeStart) || startDate.isAfter(rangeEnd)) {
includeRecurrence = false;
}

if (startDate.isSame(curEvent.start) && endDate.isSame(curEvent.end)) {
includeRecurrence = false;
}

if (includeRecurrence === true) {
// apply DST adjustment (this is zero if no adjustment)
startDate.add(dstChange, 'hours');
matchingRecurringEvents.push(cloneRecurringEvent(curEvent, startDate, endDate));

if (event.rrule.origOptions.tzid) {
// tzid present on the rrule
const eventTimeZone = moment.tz.zone(event.rrule.origOptions.tzid);
const localTimeZone = moment.tz.zone(moment.tz.guess());
const offset = localTimeZone.utcOffset(date) - eventTimeZone.utcOffset(date);
startDate = moment(date).add(offset, 'minutes').toDate();
} else {
// tzid not present on rrule (calculate offset from original start)
startDate = new Date(date.setHours(date.getHours() - ((event.start.getTimezoneOffset() - date.getTimezoneOffset()) / 60)));
}
// Set the the end date from the regular event or the recurrence override.
let endDate = moment(Number.parseInt(moment(startDate).format('x'), 10) + curDuration, 'x');

matchingRecurringEvents.push(cloneRecurringEvent(curEvent, moment(startDate), endDate));
}
}
}
Expand Down

0 comments on commit c8d52a5

Please sign in to comment.