使用此演示日历:
对于日历阅读器,输出如下所示:
但是从 npm 上的各种节点项目及其各种分支中,我得到的只是:
On 2018-10-09, Event repeating monthly on 2nd tuesday at 10am
On 2018-10-10, Event repeating weekly on a Wednesday at 11am
On 2018-10-11, Single event on 11th October
代码如下 - 一些额外的内容,因为我只对未来的日期感兴趣,并且很高兴按照即将到来的日期顺序排列事物,而不是随机的
const ical = require('ical');
var dateNow = new Date();
const url = "https://calendar.google.com/calendar/ical/ssjqjrg27h9mqqctfnr5kscmrk%40group.calendar.google.com/public/basic.ics";
ical.fromURL(url, {}, function (err, data) {
var ttsorted = [];
for (const k in data) {
const ev = data[k];
const eventStart = new Date(ev.start);
if (data.hasOwnProperty(k)) {
if (eventStart.getTime() >= dateNow.getTime()) {
const tts = `On ${ev.start.toISOString().slice(0,10)}, ${ev.summary} `;
ttsorted.push(tts);
}
}
}
ttsorted.sort();
for (const events of ttsorted) {
console.log(events);
}
});
当前的 node-ical 包可以确定在给定时间/日期范围内发生哪些重复事件。在为最终用户准备好时间之前,您最终需要自己进行一些数据处理。
来自包文档:
const ical = require('node-ical');
const moment = require('moment-timezone');
ical.fromURL('http://lanyrd.com/topics/nodejs/nodejs.ics', {}, function (err, data) {
for (let k in data) {
if (!Object.prototype.hasOwnProperty.call(data, k)) continue;
const event = data[k];
if (event.type !== 'VEVENT' || !event.rrule) continue;
const dates = event.rrule.between(new Date(2021, 0, 1, 0, 0, 0, 0), new Date(2021, 11, 31, 0, 0, 0, 0))
if (dates.length === 0) continue;
console.log('Summary:', event.summary);
console.log('Original start:', event.start);
console.log('RRule start:', `${event.rrule.origOptions.dtstart} [${event.rrule.origOptions.tzid}]`)
dates.forEach(date => {
let newDate
if (event.rrule.origOptions.tzid) {
// tzid present (calculate offset from recurrence start)
const dateTimezone = moment.tz.zone('UTC')
const localTimezone = moment.tz.guess()
const tz = event.rrule.origOptions.tzid === localTimezone ? event.rrule.origOptions.tzid : localTimezone
const timezone = moment.tz.zone(tz)
const offset = timezone.utcOffset(date) - dateTimezone.utcOffset(date)
newDate = moment(date).add(offset, 'minutes').toDate()
} else {
// tzid not present (calculate offset from original start)
newDate = new Date(date.setHours(date.getHours() - ((event.start.getTimezoneOffset() - date.getTimezoneOffset()) / 60)))
}
const start = moment(newDate)
console.log('Recurrence start:', start)
})
console.log('-----------------------------------------------------------------------------------------');
}
});