日历和活动

本指南介绍了日历、事件及其相互关系。

日历

日历 是一组相关事件,以及 摘要、默认时区和地点等其他元数据。每个日历都有一个 ID(即电子邮件地址)。日历可以与他人共享。 主日历归其关联的用户账号所有;其他日历归单个数据所有者所有。

事件

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

事件类型

Google 日历支持单次事件和周期性事件:

  • 单次事件表示一次性活动。
  • 周期性事件定义多次活动。

事件还可以是定时事件全天事件

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

组织者

事件有一个组织者,即包含事件主要副本的日历。 事件还可以有多个 参加者。 参加者通常是受邀用户的主日历。

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

日历和活动概念模型

主日历和其他日历

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

除了主日历之外,您还可以明确创建任意数量的其他日历。您可以修改、删除这些日历,并与他人共享。此类日历只有一个数据所有者,该所有者拥有最高权限,包括删除日历的专属权利。数据所有者的访问权限级别无法降级。数据所有者最初被确定为创建日历的用户,但可以在 Google 日历界面中转移数据所有权。

日历和日历列表

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

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

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

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

周期性活动

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

如果事件按照定义的日程安排重复发生,则称为周期性事件。 单次事件是非周期性的,只会发生一次。

重复规则

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

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

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

重复字段包含一个字符串数组,表示 RRULERDATEEXDATE 属性,如 RFC 5545 中所定义。

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:00 到上午 7:00 发生的活动,在 2015 年 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 日和 6 月 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 日历 API 处理周期性活动和实例的示例,请参阅周期性活动

时区

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

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

日历时区

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

查询结果时区转换
get()`get()`、 list()`list()` 和 instances()`instances()` 方法的结果以您在 timeZone 参数中指定的时区返回。如果您省略此参数,则这些方法都将使用日历时区作为默认时区。
将全天事件与时间范围查询匹配
The 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 字段会将时区附加到事件,就像 您使用日历 界面设置事件时区一样

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

周期性活动时区

对于周期性事件,您必须始终指定单个时区才能展开事件的重复活动。