任务架构

为 Android 日历事件保留模型提议的时区语义

把自然语言日期时间转为用户可确认的日历草稿,同时区分浮动时间、UTC、TZID、本地时区缺口与重叠。

审核状态: 内容已校验;中文稿供用户审核 · 2026-10-08 · Fact IDs: FUNCTION-01, ANDROID-PRIVACY-01, ANDROID-CALENDAR-TIME-2026-10

直接回答

模型生成的日期或时间是提议,不是已解析的日历时刻。交接事件之前,保留源文字并明确相对短语(如“明天”)的参考日期、目标时区、时间是绝对瞬间还是本地墙钟时间,以及用户是否指全天日期。不要在事件属于其他地点时默默改用设备当前时区,也不要把不完整短语猜成精确开始时间。上下文不足时展示待补充字段的草稿,不要猜。 iCalendar 区分多种有效表示。UTC DATE-TIME 以 Z 结尾;绑定本地时区的 DATE-TIME 使用 TZID 以及相应的 VTIMEZONE 定义;既无 Z 也无 TZID 的本地时间是浮动时间,保留墙钟值而不表示全球唯一时刻。RFC 5545 规定只有确实符合该行为时才使用浮动时间;多数固定约会应明确给出 UTC 或带时区引用的本地时间。只有日期的 DATE 与带时刻的 DATE-TIME 也是不同值类型。应保留这一区别;不要把仅日期事项改成定时事件的午夜,也不要在未核对目标日历契约前发明全天事件编码。 夏令时变更会让墙钟时间产生歧义或不存在。对于给定时区,普通本地时间有一个有效 offset;跳时缺口有零个,回拨重叠有两个。Android java.time 的 ZoneRules.getValidOffsets() 可在 API 26 及以上揭示这些情况。转换助手可能悄悄选择默认值:ZonedDateTime.of() 会把缺口时间向前调整,并在重叠时选择较早 offset。即使这些默认对某个公开策略有用,也不能证明用户想要那个时刻。创建日历动作时,应要求用户解决不存在的时间或选择重叠中的哪一次;不能把解析器默认值当作同意。 RFC 的解析规则与应用的新建事件策略是两回事。RFC 5545 定义了符合规范、带 TZID 的 iCalendar DATE-TIME 在本地时间重叠或落入夏令时缺口时如何解释:重叠选择第一次出现,缺口按变更前的 UTC offset 解释。应用根据含糊自然语言新建事件时,不能把文件标准规定的解释误当成人的意图。若要导出 ICS,应为每个 TZID 保留或生成正确的 VTIMEZONE,并且只写入已解析值;若仍有不确定性,留在可编辑草稿或不提供事件时间。 Android CalendarContract.Events 将 DTSTART 和 DTEND 表示为 UTC epoch 毫秒,并单独保存 EVENT_TIMEZONE。因此,本地日期时间必须用已选定的时区和 offset 解析后才能转换为 epoch 毫秒;把本地时钟数字直接塞入毫秒字段会改变事件瞬间。CalendarContract.Events 从 API 14 起提供;Provider 插入要求 DTSTART、EVENT_TIMEZONE 和 calendar_id;非重复事件还需 DTEND(重复事件则使用 duration 和重复字段)。其官方 allDay=1 契约要求 EVENT_TIMEZONE="UTC",时间落在午夜边界。应保留用户选择的日期并遵循目标约束,不要把日期先按手机当前时区转换成定时瞬间。 Android 日历交接有两条不同路径。面向用户的 ACTION_INSERT 搭配 Events.CONTENT_URI 与 begin/end extras,可用 epoch 毫秒预填日历编辑器;启动 intent 不证明用户已保存。处理器查询只是预检,Android 包可见性可能过滤结果,因此不能把空 resolution 当作所有设备都没有日历的证明。处理实际启动失败,不要仅为编辑器交接申请日历写权限。直接写 CalendarContract Provider 是另一种集成方式,涉及应用权限、可访问日历/帐户、Provider 行为和明确保存策略。后续 Provider 查询也需要自己的授权和可靠事件身份,不能只猜标题/时间就认定保存。预填 extras 不赋予直接写入权限或提交证明。 设备上的日历未必只保存在本机。目标帐户可能将已存事件同步到服务或其他设备。离开本地解析阶段前,应展示目标并让用户检查标题、日期、开始与结束时间、时区、地点和参会人。不要把模型任意文本写进参会人字段,或未单独确认就发送邀请。本地推理不代表日历帐户是本地帐户;调用日历应用也跨越应用边界。模型置信度和用户授权必须分开处理。 通过固定矩阵测试,而不是依赖一条流畅样例。覆盖 UTC、带时区的本地时间、有意的浮动时间、仅日期值、DST 缺口、重叠的两次出现、缺参考日期、事件地点与设备时区不同、跨转换的结束时间、格式错误输出、用户修正和取消。分别验证 iCalendar 序列化、Android epoch 转换、CalendarContract 或 ACTION_INSERT 交接。记录 locale、参考日期、所选时区、可用时的时区规则版本、源文本片段、最终决策和日历应用的实际行为。本文是通用集成方法,不声称 Cove 当前会提出或创建日历事件。

本地助手提议在重复小时中开会

合成测试使用“明天 1:30 在车站附近见面”,并特意选择使事件所在地 1:30 重复出现的参考日期和时区;手机时区不同。这是夹具条件,不宣称读者所在地的明天会发生时钟转换。

决策

保留原始文本,从经过确认的上下文确定事件地点时区,检测两个有效 offset,并在创建日历交接前询问用户选择哪次。

预期结果

编辑器收到具体、可审查的事件草稿,或保留为尚未解决的提议;不会让设备时区或库默认值悄悄决定实际时刻。

需要收集的证据

只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:

  • FUNCTION-01:模型可提出结构化动作,但格式化能力不等于应用授权或用户同意。
  • ANDROID-PRIVACY-01:权限、数据访问、存储与用户控制仍由应用负责。
  • ANDROID-CALENDAR-TIME-2026-10:iCalendar 时间类型、CalendarContract 与 Android 时区解析边界。
  • RFC 5545、CalendarContract.Events、Android 常见 intent 与 ZoneRules 官方文档定义序列化、时区和交接要求。

任务质量需要有版本记录的语料和验收规则;流畅的单条样例不等于准确度结果。

实施流程

  1. 保留源文字和参考上下文. 记录用户原话、参考日期时间、locale、事件地点及用户选择的时区。没有参考点就无法复现“明天”等相对日期,不要从模型置信度推断。
  2. 选择时间值类型. 分类为仅日期、UTC 瞬间、带时区的本地 DATE-TIME,或有意浮动的墙钟时间。把 RFC 5545 的解析规则与应用创建事件的策略分开。
  3. 明确解析时区转换. 对选定区域和本地时间调用 ZoneRules.getValidOffsets:一个表示普通时刻,零个是缺口,两个是重叠。让用户解决缺口或选择重叠中的一次,不默默用库默认值。
  4. 只把已确认瞬间映射到 Android 字段. 将已确认的带时区时间转换为 CalendarContract DTSTART/DTEND 的 epoch 毫秒并保留 EVENT_TIMEZONE。全天 DATE 应单独处理;编码前先核对目标 Provider 约束。
  5. 交接供用户复核并测试结果. ACTION_INSERT 仅用于预填编辑器,直接写 Provider 则走单独授权流程。测试保存、编辑、取消、无可用处理器、同步帐户与参会人;打开编辑器不等于收到已保存回执。

让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。

验收标准

  • 每个解析后的时间都能追溯至源文本、参考日期、预期时区,以及浮动或固定瞬间的明确选择。
  • 通过 ZoneRules 检出的缺口/重叠都要由用户或明确披露的产品策略解决;不能把解析默认值当成用户意图。
  • RFC 5545 DATE/DATE-TIME/UTC/TZID/浮动时间保持不同语义;Android 定时字段使用已解析 epoch 毫秒和明确的时间区。
  • 日历启动、用户保存、Provider 写入、帐户同步和邀请是不同状态;没有证据与授权就不宣称事件或外部操作完成。

决策对照表

维度选择或证据解读方式
UTC 瞬间源内容明确表示一个绝对时刻时使用。iCalendar 使用 UTC 标记;Android 定时字段保存解析后的 epoch 毫秒。
TZID 本地时间固定约会以已知的民用时区本地时间描述时使用。iCalendar 需要相应时区定义;Android 同时保存解析瞬间和 EVENT_TIMEZONE。
浮动本地时间仅当事件应对每位接收者保持相同墙钟时刻时使用。它没有绑定时区;不同时区的接收者可能对应不同绝对瞬间。
有歧义的模型提议上下文不足时保留为可编辑、未解决的草稿。缺口没有有效 offset,重叠有两个;默默选一个会代替用户决定。

需要避免的失败模式

  • 把没有时区的本地时间自动解释为手机当前时区。
  • 把 DST 缺口或重叠中的 ZonedDateTime 默认解析当作用户意图。
  • 将本地时钟数字直接放入以 epoch 毫秒表示的 DTSTART/DTEND。
  • 把 ACTION_INSERT 打开编辑器、Calendar Provider 写入或用户保存混为一个成功状态。
  • 因为推理在本地运行就声称日历帐户不会同步或邀请不会发出。

还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。

最小复现记录

层级记录内容
设备厂商、型号、芯片、内存档位、操作系统版本
软件应用版本和 Git 提交号
模型系列、变体、版本、格式、文件长度、摘要、量化方式
运行时名称、版本、请求后端及实际后端证据
工作负载样例版本、输入摘要、提示词摘要、输出策略
结果完成、失败、取消、回退及保护隐私的诊断信息

发布检查表

  • ☐ 主要搜索问题已回答,且没有未经支持的数字。
  • ☐ 所有模型文件和运行时版本均已固定。
  • ☐ 代表性任务和失败处理策略均有说明。
  • ☐ 生命周期、取消、清理和回退均已测试。
  • ☐ 用户内容与网络边界均有说明。
  • ☐ 结论只适用于被记录的配置。
  • ☐ 新增测试结果时链接到原始方法或证据。

来源与相关证据

中文部署与排错专题见。奇连 AI 端侧专题。

常见问题

没有 TZID 的本地时间可以当成设备本地时间吗?

不能自动这样做。RFC 5545 将既无 UTC 标记也无 TZID 的 DATE-TIME 定义为浮动时间。若需要一个固定时刻,应从用户确认的上下文取得明确时区。

模型提议落入夏令时缺口时该怎么办?

检测 ZoneRules 返回零个有效 offset,并请求澄清或采用明确披露的产品策略。不要因为日期时间构造器有默认行为就静默把事件向后挪。

启动 ACTION_INSERT 能证明事件已经保存吗?

不能。它只是预填另一个应用的编辑器。只有在文档化结果或独立 Provider 查询能证明用户提交后,才把状态改为已保存。

保存到 Android Calendar 就保证事件留在本机吗?

不能。目标日历可能随帐户同步。尽可能展示目标帐户;没有目标日历同步行为的证据时,不要宣称此交接仅在本地。