piapia123
zh

日历文件读取

转换

所有处理都在浏览器本地完成,数据不上传服务器

输入
把文件拖到这里可直接载入
输出

`.ics` 是日历通用的交换格式(RFC 5545),从 Google 日历、Outlook、Apple 日历导出的都是它。它的问题不是打不开,而是不好读:一个事件是一个 `BEGIN:VEVENT` 块,而你想要的「下周四下午三点、每周一次、到年底」分散在 `DTSTART`、`RRULE`、`UNTIL` 三个字段里,中间还夹着几十行 `VTIMEZONE` 定义。这个工具把它读成一张表。 ⚠️ 默认不做任何时区换算:带 `TZID` 的时间显示成文件里写的那个钟点,并把时区名标出来 —— 那是原始事实,换算是派生出来的,两者分别列出来才核对得了。 要换算的话,在选项里填一个 IANA 时区名(`Asia/Shanghai`、`America/New_York`、`UTC`),每个事件就会多一行「那个时刻在你选的时区里是几点」,并标出当天的 UTC 偏移。 ⚠️ 这一步不是拿一个固定偏移去减:偏移由平台自带的时区数据库算,所以是按事件那一天取的(纽约 1 月是 −05:00、7 月是 −04:00),历史上的规则变更也在里面。两种边界情况会被明确标出来:夏令时跳过的钟点在该时区不存在(不掰到邻近时刻),回拨重复的钟点对应两个时刻(取较早的那个并注明)。 ⚠️ 另外,「没有 `Z` 也没有时区名」的时间是浮动时间,意思是「谁看都是当地这个钟点」,跨时区发出去时每个人的本地时间都一样 —— 这与「某个确定的时刻」是两回事,这里会标出来。凡是这类时间,结果里都会附上说明。全部在浏览器本地完成。

功能

  • 每个事件:摘要、开始与结束时间、时长、地点、描述(可选)、状态、UID
  • 组织者与全部参与者(有 `CN` 显示名字,没有就显示地址)
  • ⚠️ 重复规则读成一句人话:「每周(周四)共 4 次」,而不是 `FREQ=WEEKLY;BYDAY=TH;COUNT=4`
  • ⚠️ 认不出的重复修饰符原样附在句尾 —— 不假装看懂了,因为那些条件恰恰决定某一次到底发生不发生
  • 提醒数量(`VALARM` 子组件)
  • 全天事件标出「全天」,时长按天算
  • 汇总:事件数、带重复规则的、带提醒的、整体时间范围
  • ⚠️ 正确处理 RFC 5545 的折行(一行上限 75 字节,续行以空格开头)—— 展开错了会在正文里凭空多出空格或把词断成两截
  • ⚠️ 默认不做时区换算,只如实呈现文件里的钟点并标出时区名与「浮动时间」
  • ⚠️ 可以按任意时区查看:填一个 IANA 时区名,每个事件多给一行换算后的钟点与当天的 UTC 偏移
  • 偏移按事件那一天取,不是按今天 —— 跨夏令时的两个日期会给出不同的偏移
  • 夏令时跳过的钟点(该时区不存在)与回拨重复的钟点(对应两个时刻)都会被明确标出,而不是悄悄掰到邻近的一个
  • 换算那一行与「文件原样」那一行并存,原样那一行不被替换
  • 全部在浏览器本地完成,文件不上传

使用方法

  1. 把 .ics 文件的全部内容粘进去(从 BEGIN:VCALENDAR 到 END:VCALENDAR)
  2. 需要看事件正文就勾上「一并输出事件的描述」
  3. 结果按事件分块列出,最后附上时区说明

常见问题

为什么不把时间换算成我所在时区?
因为正确换算需要该时区在那个具体日期上的偏移,而这不是一个固定值。夏令时规则改过很多次,有些国家改过好几次、有些取消了、有些时区的名称本身就有歧义。拿着 `Europe/London` 去查一个固定偏移,在夏令时生效的那几个月里就会错一小时 —— 而用户完全看不出来,只会按错的时间安排事情。所以这里显示文件里写的钟点并把时区名标出来:错的时间比没有时间更糟,而原始信息你随时可以自己对照。
「浮动时间」是什么?
不带宽带 `Z` 后缀、也没有时区名的时间,在 iCalendar 里的含义是「当地时间的这个钟点」—— 也就是说,这个事件在东京是 14:00,在伦敦也是 14:00,每个人的本地时间一样。它适用于「每天早上 7 点吃药」这类与地点无关的事。一旦把它当成某个确定的时刻去做换算,就会得出一个看似合理但其实错的结果。所以这里会把它标出来。
为什么不换算成我自己的时区?
默认不换算是故意的:文件里写的钟点与它的时区名是原始事实,换算是从那里派生出来的 —— 两者并排列出来,才核对得了换算对不对。要换算就在选项里填一个 IANA 时区名。⚠️ 而且那时也不是拿一个固定偏移去减:偏移由平台自带的时区数据库按事件那一天给出(夏令时规则改过很多次,不是一个固定值;给 `Europe/London` 套一个固定值,一年里有好几个月都差一小时)。被夏令时跳过或回拨重复的钟点会明确标出来,而不是悄悄掰到邻近的一个 —— 错的时间比没有时间更糟。
为什么有些重复规则的说法后面还跟着一串 `BY...=`?
因为那是没有读懂的修饰符,而它们往往正是决定某一次到底发生不发生的东西。比如 `BYDAY=-1FR`(每月最后一个周五)与 `BYSETPOS=-1`(取当月的最后一次)单独看都能认出来,组合起来的语义却需要完整的展开算法才能确定。这里只把认识的几个渲染成人话,剩下的原样附在句尾 —— 宁可让用户看到原始条件,也不要给一个看着通顺、却漏了关键限定的句子。
为什么描述里的文字有时候会粘在一起?
那多半说明文件是被别的工具改过的。RFC 5545 规定一行不超过 75 个字节,超出的部分要折到下一行、续行以一个空格开头;正确的展开是纯拼接、不加分隔符。有些工具在重新保存时按自己的规则换行,或者把折行处理成「加一个空格」,于是还原出来就多出了空格。这里按标准做,如果你看到的文本有异常的空格,来源是生成那个文件的一方。
能直接导出成 CSV 吗?
目前没有。结果可以整段复制,也可以逐行复制 —— 每一行的值单独可复制,方便贴进表格软件。真正要批量处理几十个日历文件的话,那已经超出浏览器里手工粘贴的范围了。

相关工具