日历和活动

本指南介绍了日历、活动以及它们之间的关系。

日历

日历是一组相关活动,以及摘要、默认时区、地点等其他元数据。每个日历都通过一个电子邮件地址形式的 ID 来标识。日历可以有多位所有者。

事件

活动是与特定日期或时间范围关联的对象。事件通过唯一 ID 进行标识。除了开始和结束日期时间之外,活动还包含其他数据,例如摘要、说明、地点、状态、提醒、附件等。

事件类型

Google 日历支持单次活动和周期性活动:

  • 单次事件表示一次独特的发生。
  • 周期性活动定义了多次发生。

活动也可以是定时活动或全天活动:

  • 定时事件发生在两个特定时间点之间。定时事件使用 start.dateTimeend.dateTime 字段来指定其发生时间。
  • 全天活动是指持续一整天或连续多天的活动。全天活动使用 start.dateend.date 字段来指定发生时间。请注意,时区字段对全天活动没有意义。

组织者

活动只有一个组织者,即包含活动主副本的日历。活动还可以有多个参加者。出席者通常是受邀用户的主日历。

下图显示了日历、活动和其他相关元素之间的概念关系:

主日历和其他日历

日历是一种与单个用户账号关联的特殊日历。系统会自动为每个新用户账号创建此日历,其 ID 通常与用户的主电子邮件地址一致。只要账号存在,其主要日历就永远无法删除,用户也无法“取消拥有”该日历。不过,您仍然可以与其他用户共享该内容。

除了主日历之外,您还可以明确创建任意数量的其他日历;这些日历可以修改、删除,也可以在多个用户之间共享。

日历和日历列表

日历集合表示所有现有日历。可用于创建和删除日历。您还可以检索或设置所有有权访问日历的用户共用的全局属性。例如,日历的标题和默认时区是全局属性。

CalendarList 是用户已添加到其列表中的所有日历条目的集合(显示在网页界面的左侧面板中)。您可以使用此方法向用户的列表中添加现有日历或从中移除现有日历。您还可以使用它来检索和设置特定于用户的日历属性的值,例如默认提醒。另一个示例是前景色,因为不同的用户可以为同一日历设置不同的颜色。

下表比较了这两个集合的操作含义:

操作 日历 CalendarList
insert 创建新的辅助日历。默认情况下,此日历也会添加到创作者的日历列表中。 将现有日历插入到用户的列表中。
delete 删除辅助日历。 从用户的列表中移除日历。
get 检索日历元数据,例如标题、时区。 检索元数据以及用户特定的自定义设置,例如颜色或替换提醒。
patch/update 修改日历元数据。 修改用户特定的日历属性。

周期性活动

有些活动会定期多次发生,例如每周例会、生日和节假日。除了开始时间和结束时间不同之外,这些重复活动通常完全相同。

如果活动按照预定的时间表重复进行,则称为周期性活动单次活动是指不会重复发生且仅发生一次的活动。

重复规则

周期性活动的安排分为两部分:

  • 其开始和结束字段(用于定义首次出现时间,就像这只是一个独立的单次活动),以及

  • 其重复规则字段(用于定义活动应如何随时间重复)。

recurrence 字段包含一个字符串数组,表示 RFC 5545 中定义的一个或多个 RRULERDATEEXDATE 属性。

RRULE 属性最为重要,因为它定义了重复活动的常规规则。它由多个组件组成。其中一些如下所示:

  • FREQ - 事件的重复频率(例如 DAILYWEEKLY)。必需。

  • INTERVAL - 与 FREQ 搭配使用,用于指定事件的重复频率。例如,FREQ=DAILY;INTERVAL=2 表示每两天一次。

  • COUNT - 相应事件应重复的次数。

  • UNTIL - 活动应重复的日期或日期时间(含)。

  • BYDAY - 应重复活动的星期(SUMOTU 等)。其他类似组件包括 BYMONTHBYYEARDAYBYHOUR

RDATE 属性用于指定活动发生时间的其他日期或日期时间。例如 RDATE;VALUE=DATE:19970101,19970120。 使用此属性可添加 RRULE 未涵盖的其他出现次数。

EXDATE 属性与 RDATE 类似,但用于指定活动应发生的日期或日期时间。也就是说,应排除这些情况。此值必须指向由重复规则生成的有效实例。

EXDATERDATE 可以有时区,对于全天活动,必须是日期(而非日期时间)。

每个属性都可以在“重复”字段中多次出现。 将所有 RRULERDATE 规则合并,再减去所有 EXDATE 规则排除的规则,即可得到最终的重复次数。

以下是一些周期性活动的示例:

  1. 一个活动从 2015 年 9 月 15 日开始,在每周二和周五上午 6 点到 7 点举行,并在 9 月 29 日第五次举行后停止:

    ...
    "start": {
     "dateTime": "2015-09-15T06:00:00+02:00",
     "timeZone": "Europe/Zurich"
    },
    "end": {
     "dateTime": "2015-09-15T07:00:00+02:00",
     "timeZone": "Europe/Zurich"
    },
    "recurrence": [
     "RRULE:FREQ=WEEKLY;COUNT=5;BYDAY=TU,FR"
    ],
    
    
  2. 从 2015 年 6 月 1 日开始,每 3 天重复一次,持续整个月,但不包括 6 月 10 日,但包括 6 月 9 日和 11 日的全天活动:

    ...
    "start": {
     "date": "2015-06-01"
    },
    "end": {
     "date": "2015-06-02"
    },
    "recurrence": [
     "EXDATE;VALUE=DATE:20150610",
     "RDATE;VALUE=DATE:20150609,20150611",
     "RRULE:FREQ=DAILY;UNTIL=20150628;INTERVAL=3"
    ],
    
    

实例和例外情况

周期性活动包含多个实例:在不同时间发生的特定活动。这些实例本身就是事件。

对重复活动的修改可以影响整个重复活动(及其所有实例),也可以仅影响个别实例。 与父周期性活动不同的实例称为例外

例如,例外情况可能具有不同的摘要、不同的开始时间,或者仅针对该实例邀请了其他参会者。您还可以完全取消某个实例,而无需移除相应周期性活动(实例取消会反映在活动的 status 中)。

如需查看有关如何通过 Google Calendar API 处理重复活动和实例的示例,请点击此处

时区

时区是指采用统一标准时间的地区。 在 Google 日历 API 中,您可以使用 IANA 时区标识符指定时区。

您可以为日历和活动设置时区。以下部分介绍了这些设置的效果。

日历时区

日历的时区也称为默认时区,因为它会影响查询结果。日历时区会影响 events.get()events.list()events.instances() 方法解释或呈现时间值的方式。

查询结果时区转换
get()list()instances() 方法的结果以您在 timeZone 参数中指定的时区返回。如果您省略此参数,则这些方法都将使用日历时区作为默认时区。
将全天活动与时间范围查询相匹配
借助 list()instances() 方法,您可以指定开始时间和结束时间过滤器,该方法会返回位于指定范围内的实例。日历时区用于计算全天活动的开始时间和结束时间,以确定这些活动是否符合过滤条件。

活动时区

活动实例具有开始时间和结束时间;这些时间的规范可能包括时区。您可以通过多种方式指定时区;以下所有方式都指定了同一时间:

  • dateTime 字段中添加时区偏移量,例如 2017-01-25T09:00:00-0500
  • 指定不含偏移量的时间,例如 2017-01-25T09:00:00,并将 timeZone 字段留空(这会隐式使用默认时区)。
  • 指定不含偏移量的时间,例如 2017-01-25T09:00:00,但使用 timeZone 字段指定时区。

您也可以根据需要以世界协调时间 (UTC) 指定活动时间:

  • 以世界协调时间 (UTC) 指定时间:2017-01-25T14:00:00Z 或使用零偏移量 2017-01-25T14:00:00+0000

在所有这些情况下,活动时间的内部表示形式都是相同的,但设置 timeZone 字段会为活动附加时区,就像您使用日历界面设置活动时区一样:

显示活动时区的屏幕截图片段

周期性活动时区

对于周期性活动,必须始终指定单个时区。 需要此权限才能展开活动的重复次数。