早上好,我是まさきん。
家人的日程,越来越多是通过AI助手录入Google日历的。方便是方便,但前几天我踩了一个小坑。全天日程不知为何提前了1天。查了原理之后想通了,于是记录下来。
※本文为发布时的信息。最新条件请以官方网站为准。
- 给全天日程传入带“+09:00”的日期时间,结果变成了前一天的全天日程
- 出问题的是时区被设成UTC的家庭共享日历
- 在Google Calendar API中,全天日程用 start.date 和 end.date 指定
- end.date 按规定要填第二天,结束日不包含在内
- 这次用带“Z”的方式修好,是配合所用AI集成接口的变通办法
发生了什么
我把AI助手(Claude)和Google日历连接了起来。家人共享的日历,也让它自动录入日程。
前几天,我在试用某个订阅服务的免费试用。是一个附带云存储的AI方案。关于要不要续订的判断日,我决定分两步设定。
第1个是中途确认使用感受的中期检查日。第2个是决定续订还是取消的最终判断日。最终判断日,我放在了取消期限的9天前。因为拖到最后一刻才判断,很可能会因为忙而不了了之。
这两天,我作为全天日程登记到了家庭日历上。把日期告诉AI让它录入,是一贯的做法。
可是打开日历一看,情况不对。12月的2个日程,都提前了1天。这关系到取消期限,哪怕错1天也让人不舒服。
原因是“+09:00”和日历的时区
一查,原因出在日期的传入方式上。通过AI创建日程时,全天的日期是带着“+09:00”指定的。“+09:00”是表示日本时间的写法。
另一方面,家庭共享日历的时区被设成了UTC。UTC是世界标准时间,比日本时间晚9小时。
比如“12月10日0点(+09:00)”,换算成UTC就是“12月9日15点”。从UTC的日历来看,这个时刻属于12月9日。所以全天日程也被当作12月9日录入了,这样想就说得通了。
我看不到所用AI集成工具的内部实现。所以具体的转换步骤我不能断言。不过,这种偏差正好可以用9小时时差来解释。
改成带“Z”重新录入后日期正确了
我试着把日期改成带“Z”的形式,重新更新了日程。“Z”是表示UTC的符号。这次就录到了正确的日期。
“12月10日0点(Z)”在UTC的日历上仍然是12月10日。不会因为时差跨到另一天。
从那以后,在这个AI集成里,我都用带Z的方式传全天日程。不过这不是正规做法。后面会讲到,原本的规范要简单得多。
全天日程是“没有时刻的日期”
这里我停下来想了想:全天日程到底是什么。
有时刻的日程,无论从世界哪里看都指同一个瞬间。东京的9点和伦敦的0点是同一个瞬间。看的地方不同,显示的时刻就不同。
而全天日程指的是“那一整天”。就像生日或截止日期,与时刻无关,日期本身才有意义。本来是不希望随时区变动的信息。
但是,如果给日期加上时刻和时区再传过去,事情就不一样了。接收方可能会把它当作“某个瞬间”处理。这个瞬间属于哪一天,由日历这边的时区决定。我想这次的偏差正是这种不一致造成的。
Google Calendar API的规范
读了Google的开发者文档,全天日程的传入方式写得很清楚。
日程的开始和结束有 date 和 dateTime 两种字段。date 是“yyyy-mm-dd”格式的日期,用于全天日程。dateTime 是带时刻的值,需要时区偏移。
| 字段 | 格式示例 | 使用场景 |
|---|---|---|
| start.date / end.date | 2026-12-10 | 全天日程 |
| start.dateTime / end.dateTime | 2026-12-10T09:00:00+09:00 | 有时刻的日程 |
| start.timeZone / end.timeZone | Asia/Tokyo | 有时刻日程的地区指定 |
此外,文档里还有一句很重要的话。对于全天日程,时区字段没有意义。
另外,开始和结束必须统一为“都带时刻”或“都是全天”。不能开始用 date、结束用 dateTime 这样混用。
也就是说,全天日程只传日期才是正解。只传日期的话,就不会受日历时区的影响。
end.date 要填第二天
另一个容易出错的是结束日。文档中写着,开始是“包含”,结束是“不包含”。
如果是只有12月10日一天的全天日程,end.date 要填第二天12月11日。官方示例中,6月1日的全天日程 end 也是6月2日。
"start": { "date": "2026-12-10" },
"end": { "date": "2026-12-11" }
如果 end 也填12月10日,期间就变成了零。按人的直觉有点奇怪,但记住这是规定就好。
这次的带Z是“配合接口的变通办法”
这一点我想老实地区分清楚。
按照API规范,全天日程用 start.date 和 end.date 传入才是正道。而我用的是连接AI和日历的集成工具。在它的接口里,全天日程似乎也是以日期时间的形式接收的。
在这种实现下,能正确录入UTC日历的写法恰好是带Z。能自己直接调用API的人,我觉得老老实实只传日期就好。
- 用带Z的0点传入的方法,可能只是因为日历是UTC才成功
- 如果日历时区不同,也可能偏到别的日期
- 最好先确认一下所用工具的接口是怎么传全天日程的
按传入方式整理结果
从原理上,我把传入方式和日历时区的组合排了一下。日期是说明用的例子。实际试过的只有UTC日历的2种情况。其余是根据时差推算的,仅供参考。
| 传入方式(本意是12月10日) | UTC的日历 | 日本时间的日历 |
|---|---|---|
| 12月10日0点 +09:00 | 偏到了12月9日(亲身经历) | 应该是12月10日 |
| 12月10日0点 Z | 录入为12月10日(亲身经历) | 应该是12月10日 |
| 只传日期(2026-12-10) | 12月10日 | 12月10日 |
在日本时间的日历里,Z的0点相当于日本早上9点。所以按计算日期不会偏。不过,在比UTC更靠西的地区的日历里,按计算会偏到前一天。无论哪种情况都稳定的,还是只传日期的方式。
自动化家庭日历的人容易踩的坑
家人共享的日历,很多时候是和个人主日历分开另建的。读Google的帮助,上面写着时区可以按日历分别设置。
也就是说,就算自己的主日历是日本时间,共享日历也可能是别的设置。这次的家庭日历为什么是UTC,来龙去脉我自己也说不清。老实说,就是一直没注意到就在用了。
手动录入日程的时候,这种差异可能不太会显现。开始自动化、通过API录入之后,才会突然冒出来吧。
开发者文档里写着,日历的时区也被称为“默认时区”。据说获取日程列表时,也以这个时区为基准。要做自动化的话,先看一眼日历设置没有坏处。
确认日历时区的步骤
按照Google日历的帮助,在电脑上的确认步骤如下。
- 在电脑上打开Google日历
- 在左侧“我的日历”中,把鼠标移到目标日历上
- 从“更多”图标打开“设置和共享”
- 查看日历设置里的“时区”
- 想修改的话,搜索并选择城市或国家
整体的“主要时区”在右上角设置图标打开的设置画面里。它和各日历的设置是两回事,最好两边都看一下。
不过,帮助里也注明了“如果不是活动的组织者就无法更改”。要改共享日历的设置,找创建者可能更快。
登记后要确认的事
就算修好了机制,最后还是亲眼看最可靠。我定下的确认要点有以下3个。
- 在日历上按日期亲眼确认登记的日程
- 如果是全天日程,看结束日是否为第二天
- 在共享的家人手机上,也确认显示在同一天
尤其是取消期限这类“偏了就麻烦的日程”,我会仔细看。这次也是靠亲眼看才发现的。
常见的失败和陷阱
根据自己的经历和官方文档,整理了可能出现的问题。
- 给全天日程加上时刻和时区传入
- 以为自己的主日历和共享日历时区一样
- end.date 填了和开始日相同的日期
- 开始用日期、结束用日期时间,混用格式
- 只确认登记成功,不看日期
我踩到的是第一条、第二条和最后一条。这些在刚开始自动化时可能都不容易注意到。
开始之前要确认的事
- 在设置和共享画面查看了登记目标日历的时区
- 确认了与自己的主要时区没有不一致
- 确认了工具规范能否只用日期传全天日程
- 养成了登记后查看结束日是否为第二天的习惯
- 确认过一次家人的设备上是否也显示在同一天
搭建机制时的思路
通过这次的事,我重新思考了自动化的顺序。
工作中,数据交接时也经常出现格式不一致。家人的日程,本质上也是类似的数据往来。所以我觉得,把发送方的写法和接收方的设置一起确认很重要。
以前我写过用AI把口头约定的家庭日程录入日历的故事。在把学校通知登记到日历的机制中,全天日程的 end 设成了第二天。这次关于规范的内容,也为那种做法提供了依据。
时间基准偏移的话题,在cron的日期与星期陷阱一文中也稍有提及。做自动化,与UTC打交道的方式也许很重要。
常见问题
Q. 用API创建全天日程时该用什么?
在Google Calendar API中,应使用 start.date 和 end.date。格式是“yyyy-mm-dd”的日期。dateTime 是给有时刻的日程用的,全天日程不用。
Q. end.date 该填什么?
结束是“不包含”的,所以要填最后一天的第二天。只有12月10日一天的日程,end.date 就是12月11日。官方示例也是同样的形式。
Q. 全天日程指定timeZone会生效吗?
开发者文档中说明,对全天日程来说时区字段没有意义。只传日期的话,应该不受日历时区影响。
Q. 每个日历的时区会不同吗?
Google的帮助中介绍了按日历修改时区的步骤。所以主日历和共享日历的设置有可能不同。可以在“设置和共享”画面确认。
Q. 用带Z的方式传,一定会录入正确日期吗?
我的情况是,在UTC日历上录入到了正确日期。但按计算,结果可能因日历时区而变。如果能只传日期,我觉得那样更稳定。
Q. 改不了共享日历的时区。
Google的帮助中注明,如果不是活动的组织者就无法更改。请创建日历的人看一下设置,可能更快。
Q. 已经偏了的日程该怎么修?
我是用正确的写法重新更新了日程。手动修的话,打开日程改日期就行。修好后,最好也在家人的设备上确认一下显示。
参考的官方信息
- Events(Google Calendar API 参考文档,英文)
- Calendars and events(Google Calendar API 指南,英文)
- Calendars(Google Calendar API 参考文档,英文)
- 在不同时区使用Google日历(Google日历帮助,日文页面)
总结
全天日程是“没有时刻的日期”。如果给它传入带时区的日期时间,日期可能会因日历设置而偏移。在我的家庭日历上,这表现为提前了1天。
按照API规范,全天日程只传日期,结束日填第二天。这次的带Z,定位是配合所用集成工具的变通办法。
在自动化家庭日历的朋友,不妨看一眼日历的时区。像试用的判断日这类管理期限的日程,偏了尤其麻烦。管理期限的同时,顺便看看每月的固定支出也不错。
本文包含联盟营销广告。如果您通过本站链接申请相关商品或服务,我们可能会从合作企业获得报酬。此外,运营者是乐天集团的员工,也可能通过员工推荐计划获得报酬。文章内容与评价均基于运营者的真实体验与调查完成,与是否存在广告无关,但请您在阅读前了解上述关系。详情请参阅免责声明与联盟营销说明。 免责声明与联盟营销说明
本文包含机器翻译内容。正式条件请以乐天移动官方网站的多语言页面为准。
如果您对乐天移动的通信区域·信号状况有疑问,可以通过官方的 电波改善调查申请表 进行咨询。