苹果手机 ios 提醒事项同步日历(单项同步)
说明:我主要使用日历,每天的规划就在提醒事项中写,然后就能自动同步到日历了功能包含
- 未完成日历显示❌、已完成✅、待完成⭕️
- 一个提醒事项默认日历为半小时
- 已完成的日历,会标注具体完成的时间如 2023年 10 月 5 日 14 时 23 分完成
- 待完成显示:还剩 xx天xx 时 xx 分
- 过期显示:已过期,请及时完成
- 正在进行的日历:进行中,加油哦
- 提醒事项删除则自动删除日历
- 创建提醒事项的备注也是可以同步到日历中的
- 以上功能都可以自己任意改(欢迎评论区分享自己魔改的代码)
- 源码最初版来源网上,作者不知道是谁,自定义程度不高,我进行了一些改动,并在代码加了注释,可以按照自己的需求任意改动。
// 设置查询的时间范围为当前时间前后一个月
var dur_month = 1;
// 获取当前时间,并设置开始时间为一个月前
const startDate = new Date();
startDate.setMonth(startDate.getMonth() - dur_month);
console.log(`日历的开始时间 ${startDate.toLocaleDateString()}`);
// 设置结束时间为一个月后
const endDate = new Date();
endDate.setMonth(endDate.getMonth() + dur_month);
console.log(`日历的结束时间 ${endDate.toLocaleDateString()}`);
// 获取这个时间范围内的所有提醒事项
const reminders = await Reminder.allDueBetween(startDate, endDate);
console.log(`获取 ${reminders.length} 条提醒事项`);
// 获取所有可用的日历
var calendar = await Calendar.forEvents();
// 创建一个字典来存储日历的名称和对应的日历对象
var m_dict = {};
for (cal of calendar) {
m_dict[cal.title] = cal;
}
// 获取这个时间范围内的所有日历事件
const events = await CalendarEvent.between(startDate, endDate, calendar);
console.log(`获取 ${events.length} 条日历`);
// 创建一个集合来存储所有提醒事项的标识符
var reminders_id_set = new Set(reminders.map(e => e.identifier));
// 过滤出所有包含"[Reminder]"标记的日历事件
var events_created = events.filter(e => e.notes != null && e.notes.includes("[Reminder]"));
for (let event of events_created) {
// 使用正则表达式从事件的备注中提取提醒事项的标识符
let reg = /(\[Reminder\])\s([A-Z0-9\-]*)/;
let r = event.notes.match(reg);
// 如果这个提醒事项已经被删除,则删除对应的日历事件
if (!reminders_id_set.has(r[2])) {
event.remove();
}
}
// 遍历所有提醒事项
for (const reminder of reminders) {
// 创建一个特定格式的备注,用于在日历事件中标识这个提醒事项
const targetNote = `[Reminder] ${reminder.identifier}`;
// 查找是否已经有一个对应这个提醒事项的日历事件
const [targetEvent] = events.filter(e => e.notes != null && e.notes.includes(targetNote));
// 如果找不到对应的日历,则跳过这个提醒事项
if (!m_dict[reminder.calendar.title]) {
console.warn("找不到日历" + reminder.calendar.title);
continue;
}
// 如果找到了对应的日历事件,则更新这个事件
if (targetEvent) {
updateEvent(targetEvent, reminder);
} else {
// 否则,创建一个新的日历事件
console.warn(`创建事项 ${reminder.title} 到 ${reminder.calendar.title}`);
const newEvent = new CalendarEvent();
// 确保不添加undefined到日历备注
newEvent.notes = targetNote; // 首先设置为targetNote
if (reminder.notes) { // 如果reminder.notes不是undefined或null
newEvent.notes += "\n" + reminder.notes; // 则添加到备注中
}
updateEvent(newEvent, reminder);
}
}
// 完成脚本执行
Script.complete();
// 更新或创建日历事件的函数
function updateEvent(event, reminder) {
const nowTime = new Date();
// 完成时的时间格式化
const completedTimeFormat = `${nowTime.getFullYear()} 年 ${nowTime.getMonth() + 1} 月 ${nowTime.getDate()} 日 ${nowTime.getHours()} 时 ${nowTime.getMinutes()} 分完成`;
const dueDate = new Date(event.endDate); // 获取日历事件的截止时间
const startDate = new Date(event.startDate); // 获取日历事件的开始时间
if (reminder.isCompleted) {
event.title = `✅${reminder.title}`;
event.location = completedTimeFormat;
} else if (nowTime < startDate) { // 当前时间早于日历事件的开始时间
const periodMs = startDate - nowTime;
const periodDays = Math.floor(periodMs / 1000 / 3600 / 24);
const periodHours = Math.floor((periodMs % (1000 * 3600 * 24)) / (1000 * 3600));
const periodMinutes = Math.floor((periodMs % (1000 * 3600)) / (1000 * 60));
event.title = `⭕️${reminder.title}`;
event.location = `还剩 ${periodDays} 天 ${periodHours} 时 ${periodMinutes} 分`;
} else if (nowTime >= startDate && nowTime <= dueDate) { // 当前时间在日历事件的开始时间和截止时间之间
event.title = `⭕️${reminder.title}`;
event.location = `进行中,加油哦`;
} else if (nowTime > dueDate) { // 当前时间晚于日历事件的截止时间
event.title = `❌${reminder.title}`;
event.location = `已过期,请及时完成`;
}
let cal_name = reminder.calendar.title;
let cal = m_dict[cal_name];
event.calendar = cal;
if (!reminder.dueDate) {
const startTime = new Date();
startTime.setMinutes(startTime.getMinutes() + 30);
event.startDate = startTime;
const endTime = new Date(startTime);
endTime.setMinutes(endTime.getMinutes() + 30);
event.endDate = endTime;
} else if (!reminder.dueDateIncludesTime) {
const startTime = new Date(reminder.dueDate);
startTime.setHours(8, 0, 0, 0);
event.startDate = startTime;
const endTime = new Date(startTime);
endTime.setMinutes(endTime.getMinutes() + 30);
event.endDate = endTime;
} else {
const dueDate = new Date(reminder.dueDate);
event.startDate = dueDate;
const endTime = new Date(dueDate);
endTime.setMinutes(endTime.getMinutes() + 30);
event.endDate = endTime;
}
event.save();
}