紧凑时长格式(Compact Duration Format)2.0 版。定义语法、合法形式、规范形式、进位、数值范围、展示原则和失败情形;1.0 的表示继续有效,只表示非负时长,月份与年份仍被排除。

1 版本说明

本文定义紧凑时长 1格式(Compact Duration Format)的 2.0 版。1.0 定义的表示在 2.0 中仍然有效,数值含义不变。

与 1.0 相比,2.0 明确以下内容:

  • 完整的词法与语法;
  • 合法形式与规范形式;
  • 单位进位与数值范围;
  • 非负约束;
  • 展示形式的选择原则;
  • 统一的失败情形。

3w2d1h20m33s 等 1.0 写法在 2.0 中仍然合法,数值含义不变。

2 规范用语

本文中的「必须」「不得」「应」「不应」「可以」按 RFC 2119 解释:

用语 含义
必须 绝对要求
不得 绝对禁止
应 推荐;有充分理由时可以偏离,但应理解其后果
不应 不推荐
可以 可选

3 设计目标

工程配置里常见的 timeout: 3600 需要翻文档确认单位;自由文本 2小时30分 人类易读但机器难以统一解析;ISO 8601 的 P3W2DT1H20M33S 足够严谨,但在配置、日志和状态描述中读写成本偏高。

紧凑时长格式面向项目内部的高频读写场景,目标如下:

  • 人工可以直接读出时长;
  • 机器可以无歧义地解析为精确数值;
  • 任意两个表示可以按数值比较;
  • 展示可以优先人类阅读;
  • 规范只约束语法和数值语义,不约束展示形式的选择。

本格式是项目级规范,不追求覆盖 ISO 8601 的全部日历语义,也不宣称在语法上与其兼容。

4 语法

4.1 词法

Duration = UnitPart+ ;
UnitPart = Number Unit ;
Number   = Digit+ ;
Digit    = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
Unit     = "w" | "d" | "h" | "m" | "s" | "ms" | "us" | "ns" ;
  • 字符串必须只包含 ASCII 字符。
  • 单位必须为小写;大写不属于合法形式。
  • 各时间单元之间不得包含空格、制表符或其他分隔符。
  • 单位必须按最长匹配识别:在数字之后依次尝试 ns、us、ms、w、d、h、m、s。因此 500ms 必须解释为 500 毫秒,不得解释为 500 分钟加一个孤立的 s。
  • 本格式不包含符号位;负值不属于本格式。

4.2 单位

核心单位必须支持:

单位 含义 等价关系
w 周 7d
d 天 24h
h 小时 60m
m 分钟 60s
s 秒 基础单位

扩展单位可以支持:

单位 含义 等价关系
ms 毫秒 1/1000 s
us 微秒 1/1000 ms
ns 纳秒 1/1000 us
  • 实现必须支持全部核心单位。
  • 实现可以支持扩展单位;支持的扩展单位集合由实现确定。
  • 使用方不得假定扩展单位一定被支持。
  • 对于不支持的扩展单位,解析必须失败,不得静默舍入或截断。

4.3 保留单位

y(年)、mo(月)、a(年)为保留单位,不属于本格式,必须拒绝。

月份长度为 28 至 31 天,年份长度为 365 或 366 天,都无法无歧义地换算为固定秒数。需要日历周期时,应使用独立的格式,不得混入本格式。

4.4 顺序

多个单位同时出现时,必须按时间尺度由大到小排列:

w → d → h → m → s → ms → us → ns

单位必须严格降序,且不得重复。顺序固定之后,格式才不需要任何分隔符。

4.5 非负约束

本格式只表示非负时长。负值表示方向,不属于时长本身;需要在格式之外表达。

5 合法形式与规范形式

本规范定义两种表示:合法形式和规范形式。

  • 合法形式是语法上可以解析的表示。
  • 规范形式是一种确定性的默认表示,便于需要固定字符串的场合。

规范保证的唯一性是数值唯一:任何合法形式都必须解析为同一个精确数值,而不是要求所有实现输出同一个字符串。

5.1 合法形式

满足以下条件的字符串是合法形式:

  1. 符合词法定义;
  2. 至少包含一个时间单元;
  3. 单位严格降序,且不重复;
  4. 只使用核心单位或实现支持的扩展单位;
  5. 数值为非负十进制整数,可以包含前导零;
  6. 总时长不超过本规范规定的最大值。

合法形式不是唯一表示。例如 90s 与 1m30s 都是合法形式,且表示同一时长。

5.2 规范形式

规范形式是确定性的默认表示,必须同时满足:

  1. 数字不含前导零;
  2. 除整体的 0s 外,不得包含值为 0 的时间单元;
  3. 必须按进位关系完成全部可进位;
  4. 单位严格降序,且不重复;
  5. 零时长必须表示为 0s;
  6. 只使用核心单位或实现支持的扩展单位。

规范形式是推荐的固定字符串表示。它不是唯一的合法表示,展示可以使用其他合法形式。

6 进位

规范形式中的进位关系如下:

低位表示 等价高位表示
1000ns 1us
1000us 1ms
1000ms 1s
60s 1m
60m 1h
24h 1d
7d 1w

在规范形式中,必须按此表完成全部可进位。展示形式不受此限制。

以下示例假定扩展单位已支持:

输入 规范形式
60s 1m
90m 1h30m
24h 1d
7d 1w
30d 4w2d
2h0m30s 2h30s
1h60m 2h
1000ms 1s
1s1000ms 2s
1w7d 2w
01s 1s
0m 0s

7 数值范围

本规范表示的最大时长为 2^63−1 纳秒,约为 292 年。

  • 实现必须支持 0 到最大值的完整范围。
  • 总时长超过最大值的表示不是合法形式,解析必须失败。
  • 不得回绕、截断或饱和。

8 解析与校验

  • 解析合法形式必须得到精确的总时长。
  • 需要确定字符串表示时,应生成规范形式。
  • 比较必须按总时长进行,不得按字符串进行。
  • 实现可以提供严格校验;严格校验只接受规范形式,其他输入必须失败。
  • 大小写混写、空格分隔、µs、中文长写等不属于合法形式。

9 失败情形

以下情形用于区分解析失败的原因:

情形 触发条件 示例
E_EMPTY 空字符串 空串
E_LEX 含空白、小数点、负号、全角字符或其他非法字符 2h 30m、1.5h、-1h
E_UNIT 未知单位、保留单位或大小写不符 1y、1mo、1H
E_FORMAT 数字与单位配对错误 0、h、1h30
E_ORDER 单位不是严格降序 30m2h
E_DUP 同一单位出现多次 1h2h
E_PRECISION 使用了实现不支持的扩展单位 不支持 ms 时的 500ms
E_OVERFLOW 超出本规范的最大时长 999999999999999999999w
E_NONCANONICAL 严格校验下输入不是规范形式 严格校验下的 60s

10 展示

规范保证解析结果数值唯一,展示可以优先人类阅读。

  • 实现可以自行选择合适的单位展示。例如,在习惯以天读数的场景中,30d 比 4w2d 更易读;在习惯以秒读数的场景中,90s 比 1m30s 更易读。
  • 本规范不规定展示形式的选择规则,也不要求展示形式与规范形式一致。
  • 展示形式必须是合法形式。
  • 同一时长的不同展示形式必须解析为同一数值。
  • 展示形式不改变语法或数值语义。

11 与其他格式的关系

本节为定位说明,不构成规范要求。

特性 紧凑时长 2.0 ISO 8601 Duration Go time.Duration
基本写法 3w2d1h20m33s P3W2DT1H20M33S 74h20m33s
日历单位 不支持 支持年和月 不支持
固定单位 w d h m s W D H M S h m s ms us ns
小数 不支持 支持 支持
负号 不支持 视具体表示法而定 支持
分隔符 无 P、T 无
大小写 只接受小写 大写 小写
  • 需要与外部系统交换标准时长数据时,应使用 ISO 8601。
  • 本格式坚持整数,以保证精确;需要更细粒度时,使用扩展单位。
  • 本格式只表示非负时长;负值表达方向,不属于时长本身。
  • 不支持小数,是因为有限小数不一定能在有限精度内精确表示,会引入舍入和数值歧义。

12 持续时间而非时间点

紧凑时长格式表示持续时间,而不是时间点。3d12h 表示一个持续 3 天 12 小时的长度,不表示 2026-11-08 12:00 这样的时刻。时间点应使用独立的 Date-Time 或 Timestamp 格式。

把一个持续时长加到某个时间点上属于日历运算,涉及时区、夏令时和月份边界等规则,应另行定义。本格式只定义固定长度时长本身。

13 一致性测试向量

下表可用于验证解析和规范化的行为:

  • 第 1 至 9 行、第 13 至 14 行:核心单位,所有实现必须通过;
  • 第 10 至 12 行:扩展单位,仅支持对应扩展单位的实现需要通过;
  • 第 15 至 26 行:失败情形与严格校验,提供严格校验的实现需要通过。
序号 输入 行为 期望结果
1 0s 规范化解析 0s
2 30s 规范化解析 30s
3 60s 规范化解析 1m
4 90m 规范化解析 1h30m
5 24h 规范化解析 1d
6 7d 规范化解析 1w
7 30d 规范化解析 4w2d
8 2h0m30s 规范化解析 2h30s
9 1h60m 规范化解析 2h
10 1s1000ms 规范化解析 2s
11 1000ms 规范化解析 1s
12 500ms 规范化解析 500ms
13 01s 规范化解析 1s
14 1w7d 规范化解析 2w
15 1h2h 严格校验 E_DUP
16 30m2h 严格校验 E_ORDER
17 2h 30m 严格校验 E_LEX
18 1.5h 严格校验 E_LEX
19 -1h 严格校验 E_LEX
20 1y 严格校验 E_UNIT
21 1H 严格校验 E_UNIT
22 0 严格校验 E_FORMAT
23 空字符串 严格校验 E_EMPTY
24 60s 严格校验 E_NONCANONICAL
25 500ms 严格校验,实现不支持 ms E_PRECISION
26 999999999999999999999w 严格校验 E_OVERFLOW

14 从 1.0 到 2.0 的变更

14.1 兼容性

  • 五个核心单位的顺序和无分隔符写法不变。
  • 1.0 的进位和去零规则在 2.0 中继续作为规范形式的要求。
  • 1.0 的合法写法在 2.0 中仍然合法,数值含义不变。

14.2 新增与明确

项目 1.0 2.0
合法与规范 只提出应规范化 明确两种形式及其关系
数值唯一性 未明确 明确为解析结果的数值唯一
展示形式 未涉及 明确可以选择更易读的合法形式
进位 原则性描述 完整进位关系
范围 未定义 0 到 2^63−1 纳秒
扩展单位 可选 可选;不支持时必须失败
负时长 未定义 明确不支持
失败情形 未定义 统一分类
保留字 未定义 y、mo、a 必须拒绝

15 参考引用

  • RFC 2119:https://www.rfc-editor.org/rfc/rfc2119(规范性用语定义)
  • ISO 8601:https://en.wikipedia.org/wiki/ISO_8601(日期与时间表示的国际标准)
  • Go time.ParseDuration:https://pkg.go.dev/time#ParseDuration(Go 标准库的时长解析)
  • 紧凑时长格式 1.0:https://srs.pub/thinking/compact-duration.html(上一版规范)

  1. 时长表示规范. https://srs.pub/thinking/compact-duration.html↩︎