automating-calendar

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Automating Calendar (JXA with AppleScript Discovery)

日历自动化(结合AppleScript查询的JXA实现)

Contents

目录

Relationship to the macOS automation skill

与macOS自动化技能的关联

  • Use
    automating-mac-apps
    for general app permissions, shell commands, UI scripting, and cross-app automation patterns.
  • This skill focuses specifically on Calendar events, calendars, and EventKit bridge functionality.
  • PyXA Installation: To use PyXA examples in this skill, see the installation instructions in
    automating-mac-apps
    skill (PyXA Installation section).
  • 通用应用权限、Shell命令、UI脚本编写以及跨应用自动化模式请使用
    automating-mac-apps
    技能。
  • 本技能专注于日历事件、日历本身以及EventKit桥接功能。
  • PyXA安装: 若要使用本技能中的PyXA示例,请查看
    automating-mac-apps
    技能中的安装说明(PyXA安装章节)。

Core Framing

核心框架

  • Calendar dictionary is AppleScript-first; discover there
  • JXA provides logic, data handling, and ObjC/EventKit bridge access
  • PyXA offers modern Python alternative with cleaner syntax
Implementation Notes: See
automating-calendar/references/calendar-basics.md
  • 日历字典以AppleScript为优先,需在此查询相关术语
  • JXA提供逻辑处理、数据操作以及ObjC/EventKit桥接访问能力
  • PyXA提供语法更简洁的现代Python替代方案
实现说明: 详见
automating-calendar/references/calendar-basics.md

Workflow (default)

默认工作流程

  1. Discover Calendar dictionary terms in Script Editor.
  2. Prototype minimal AppleScript commands.
  3. Port to JXA with defensive error handling.
  4. Implemented batch reads (avoided heavy
    .whose()
    ).
  5. Added EventKit bridge for advanced queries.
  6. Tested with sample events and verified results.
  1. 在脚本编辑器中查询日历字典术语。
  2. 编写最小化AppleScript命令原型。
  3. 移植到JXA并添加防御性错误处理。
  4. 实现批量读取(避免使用重型
    .whose()
    方法)。
  5. 集成EventKit桥接以支持高级查询。
  6. 使用示例事件测试并验证结果。

Error Handling

错误处理

  • Wrap operations in try-catch blocks
  • Verify calendar access:
    Calendar.calendars.length > 0
  • Check event creation:
    if (!event.id()) throw new Error('Event creation failed')
  • Log operations for debugging
  • 将操作包裹在try-catch代码块中
  • 验证日历访问权限:
    Calendar.calendars.length > 0
  • 检查事件创建是否成功:
    if (!event.id()) throw new Error('Event creation failed')
  • 记录操作日志以便调试

Validation Checklist

验证清单

  • Calendar permissions granted (System Settings > Privacy & Security > Calendars)
  • Calendar access confirmed:
    Calendar.calendars.length > 0
  • Event created with valid start/end dates
  • Event visible in Calendar UI after save
  • EventKit bridge queries return expected results
  • Error handling wraps all operations
  • Output matches expected event properties
  • 已授予日历权限(系统设置 > 隐私与安全性 > 日历)
  • 已确认日历访问权限:
    Calendar.calendars.length > 0
  • 事件使用有效的开始/结束日期创建
  • 保存后事件在日历UI中可见
  • EventKit桥接查询返回预期结果
  • 所有操作均已添加错误处理
  • 输出与预期的事件属性匹配

Core Examples

核心示例

Basic Event Creation (JXA - Legacy):
javascript
const Calendar = Application("Calendar");
const event = Calendar.calendars[0].events.push(Calendar.Event({
  summary: "Meeting",
  startDate: new Date(),
  endDate: new Date(Date.now() + 3600000)
}));
Basic Event Creation (PyXA - Recommended):
python
import PyXA
from datetime import datetime, timedelta

calendar = PyXA.Calendar()
基础事件创建(JXA - 传统方式):
javascript
const Calendar = Application("Calendar");
const event = Calendar.calendars[0].events.push(Calendar.Event({
  summary: "Meeting",
  startDate: new Date(),
  endDate: new Date(Date.now() + 3600000)
}));
基础事件创建(PyXA - 推荐方式):
python
import PyXA
from datetime import datetime, timedelta

calendar = PyXA.Calendar()

Get first calendar

Get first calendar

work_calendar = calendar.calendars()[0]
work_calendar = calendar.calendars()[0]

Create event

Create event

event = work_calendar.events().push({ "summary": "Meeting", "start_date": datetime.now(), "end_date": datetime.now() + timedelta(hours=1), "location": "Conference Room A" })
print(f"Created event: {event.summary()}")

**PyObjC with EventKit (Advanced):**
```python
from EventKit import EKEventStore, EKEvent, EKCalendar
from Foundation import NSDate, NSTimeInterval
import objc
event = work_calendar.events().push({ "summary": "Meeting", "start_date": datetime.now(), "end_date": datetime.now() + timedelta(hours=1), "location": "Conference Room A" })
print(f"Created event: {event.summary()}")

**结合EventKit的PyObjC实现(高级):**
```python
from EventKit import EKEventStore, EKEvent, EKCalendar
from Foundation import NSDate, NSTimeInterval
import objc

Initialize event store

Initialize event store

store = EKEventStore.alloc().init()
store = EKEventStore.alloc().init()

Request access (async in real implementation)

Request access (async in real implementation)

store.requestAccessToEntityType_completion_(EKEntityTypeEvent, None)

store.requestAccessToEntityType_completion_(EKEntityTypeEvent, None)

Get default calendar

Get default calendar

calendars = store.calendarsForEntityType_(EKEntityTypeEvent) if calendars: default_calendar = calendars[0]
# Create event
event = EKEvent.eventWithEventStore_(store)
event.setTitle_("Meeting")
event.setStartDate_(NSDate.date())
event.setEndDate_(NSDate.dateWithTimeIntervalSinceNow_(3600))  # 1 hour
event.setCalendar_(default_calendar)

# Save event
error = objc.nil
success = store.saveEvent_span_error_(event, EKSpanThisEvent, error)

if success:
    print(f"Event created: {event.title()}")
else:
    print(f"Error creating event: {error}")

**EventKit Bridge Query (JXA - Legacy):**
```javascript
ObjC.import('EventKit');
const store = $.EKEventStore.alloc.init;
// See 'eventkit-query.md' for full predicate implementation
EventKit Bridge Query (PyObjC - Modern):
python
from EventKit import EKEventStore, EKEntityTypeEvent, NSPredicate
from Foundation import NSDate

store = EKEventStore.alloc().init()
calendars = store.calendarsForEntityType_(EKEntityTypeEvent) if calendars: default_calendar = calendars[0]
# Create event
event = EKEvent.eventWithEventStore_(store)
event.setTitle_("Meeting")
event.setStartDate_(NSDate.date())
event.setEndDate_(NSDate.dateWithTimeIntervalSinceNow_(3600))  # 1 hour
event.setCalendar_(default_calendar)

# Save event
error = objc.nil
success = store.saveEvent_span_error_(event, EKSpanThisEvent, error)

if success:
    print(f"Event created: {event.title()}")
else:
    print(f"Error creating event: {error}")

**EventKit桥接查询(JXA - 传统方式):**
```javascript
ObjC.import('EventKit');
const store = $.EKEventStore.alloc.init;
// See 'eventkit-query.md' for full predicate implementation
EventKit桥接查询(PyObjC - 现代方式):
python
from EventKit import EKEventStore, EKEntityTypeEvent, NSPredicate
from Foundation import NSDate

store = EKEventStore.alloc().init()

Get events for today

Get events for today

start_date = NSDate.date() # Today end_date = NSDate.dateWithTimeIntervalSinceNow_(86400) # Tomorrow
calendars = store.calendarsForEntityType_(EKEntityTypeEvent) predicate = store.predicateForEventsWithStartDate_endDate_calendars_( start_date, end_date, calendars)
events = store.eventsMatchingPredicate_(predicate)
for event in events: print(f"Event: {event.title()}, Start: {event.startDate()}")
undefined
start_date = NSDate.date() # Today end_date = NSDate.dateWithTimeIntervalSinceNow_(86400) # Tomorrow
calendars = store.calendarsForEntityType_(EKEntityTypeEvent) predicate = store.predicateForEventsWithStartDate_endDate_calendars_( start_date, end_date, calendars)
events = store.eventsMatchingPredicate_(predicate)
for event in events: print(f"Event: {event.title()}, Start: {event.startDate()}")
undefined

When Not to Use

不适用场景

  • Cross-platform calendar automation (use Google Calendar API or CalDAV)
  • iCloud sync operations (use EventKit directly)
  • Non-macOS platforms
  • Simple AppleScript-only tasks (skip JXA complexity)
  • Calendar sharing or permissions management (use Calendar UI)
  • 跨平台日历自动化(请使用Google Calendar API或CalDAV)
  • iCloud同步操作(请直接使用EventKit)
  • 非macOS平台
  • 仅需简单AppleScript的任务(无需引入JXA的复杂度)
  • 日历共享或权限管理(请使用日历UI)

What to load

需加载的资源

  • Calendar JXA basics:
    automating-calendar/references/calendar-basics.md
  • Recipes (events, alarms, recurrence):
    automating-calendar/references/calendar-recipes.md
  • Advanced patterns (time zones, batch reads, EventKit bridge):
    automating-calendar/references/calendar-advanced.md
  • Dictionary translation table:
    automating-calendar/references/calendar-dictionary.md
  • PyXA API Reference (complete class/method docs):
    automating-calendar/references/calendar-pyxa-api-reference.md
  • EventKit query example:
    automating-calendar/references/eventkit-query.md
  • EventKit create with recurrence:
    automating-calendar/references/eventkit-create.md
  • EventKit time zone example:
    automating-calendar/references/eventkit-timezones.md
  • EventKit exceptions/occurrences:
    automating-calendar/references/eventkit-exceptions.md
  • EventKit cancel occurrence example:
    automating-calendar/references/eventkit-occurrence-cancel.md
  • 日历JXA基础:
    automating-calendar/references/calendar-basics.md
  • 实用示例(事件、提醒、重复规则):
    automating-calendar/references/calendar-recipes.md
  • 高级模式(时区、批量读取、EventKit桥接):
    automating-calendar/references/calendar-advanced.md
  • 字典对照表:
    automating-calendar/references/calendar-dictionary.md
  • PyXA API参考(完整类/方法文档):
    automating-calendar/references/calendar-pyxa-api-reference.md
  • EventKit查询示例:
    automating-calendar/references/eventkit-query.md
  • 带重复规则的EventKit事件创建:
    automating-calendar/references/eventkit-create.md
  • EventKit时区示例:
    automating-calendar/references/eventkit-timezones.md
  • EventKit例外/实例:
    automating-calendar/references/eventkit-exceptions.md
  • 取消EventKit事件实例示例:
    automating-calendar/references/eventkit-occurrence-cancel.md