NocoBase 模板打印时间间隔格式化::formatI 语法、单位换算与人性化输出完全指南
2026/9/18 12:38:11 网站建设 项目流程

NocoBase 模板打印时间间隔格式化::formatI 语法、单位换算与人性化输出完全指南

【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase

时间间隔(时长)格式化是业务单据打印中最高频的需求之一:工单耗时、服务时长、保修周期、倒计时提示,都需要把原始的毫秒数值或 ISO 8601 时长字符串翻译成人类可读的文本。NocoBase 模板打印提供的:formatI(patternOut, patternIn)格式化器,专门用于完成这类转换——它既能输出26028这样的纯数值时长,也能输出"a few seconds""in a few seconds""a few seconds ago"这样的人性化文案,还能直接解析P1MP1Y2M3DT4H5M6S等 ISO 8601 时长字符串。读完本文,你将完整掌握formatI的全部输出单位、单位换算规则、人性化模式以及在实际打印模板中的组合用法。

1. formatI 在模板打印格式化器体系中的位置

NocoBase 模板打印的格式化器(formatter)是一组把原始数据转换成可读文本的处理器,统一通过冒号(:)应用于数据,且可以链式调用——每个格式化器的输出会作为下一个格式化器的输入,详见 格式化工具总览。其基本调用形式为:

{d.属性:formatter1:formatter2(...)}

例如,先lowerCaseucFirst,可以把"JOHN"渲染为"John"

My name is {d.name:lowerCase:ucFirst}. I was born on {d.birthday:formatD(LL)}.

formatI正是这套格式化器体系中负责"时长 / 时间间隔"处理的成员,与负责"日期时刻"的formatD(见 日期格式化)形成互补:formatD回答"这一刻是哪天几点",formatI回答"这段时间有多长、怎么读"。

2. :formatI(patternOut, patternIn) 语法说明

{值:formatI(patternOut, patternIn)}

参数定义:

参数是否必填说明
patternOut必填输出格式,例如'second''human+',决定结果以什么单位或什么风格呈现
patternIn可选输入单位,例如'milliseconds''s',用于声明原始值的单位;省略时默认按毫秒(milliseconds)解析

其中patternOut支持两大类输出格式:

  1. 人性化显示human+human(适合直接展示给最终用户阅读);
  2. 数值单位millisecond(s)second(s)minute(s)hour(s)year(s)month(s)week(s)day(s)等单位(或其简写),适合后续参与计算或按固定单位对齐展示。

单位简写约定与 diffD 日期差值计算 保持一致,例如s表示秒、ms表示毫秒、h表示小时、d表示天。此外,格式化器的常量参数如果包含逗号或空格,需要用单引号包裹(如prepend('my prefix')),formatI的格式参数同样遵循这一约定。

3. 数值输出:把毫秒换算成指定单位

patternOut指定为某个时间单位时,formatI会将输入值换算到该单位并返回数值。以下示例默认输入单位为毫秒(ms):

2000:formatI('second') // 输出 2 2000:formatI('seconds') // 输出 2 2000:formatI('s') // 输出 2 3600000:formatI('minute') // 输出 60 3600000:formatI('hour') // 输出 1 2419200000:formatI('days') // 输出 28

从这些示例可以归纳出单位换算关系与典型取值:

输入(毫秒)换算关系输出单位结果
20002000 ÷ 1000second(s)/s2
36000003600000 ÷ 60000minute(s)60
36000003600000 ÷ 3600000hour(s)1
24192000002419200000 ÷ 86400000day(s)/days28

可见单数(secondminutehourday)与复数(secondsminuteshoursdays)写法等效,简写(如s)同样被接受。换算按标准进制执行:1 秒 = 1000 毫秒,1 分钟 = 60 秒,1 小时 = 60 分钟,1 天 = 24 小时,1 周 = 7 天。需要注意的是,月(month)与年(year)属于非整数倍单位,具体折算系数见第 6 节关于 ISO 8601 解析的说明。

4. 人性化输出:human 与 human+

patternOuthumanhuman+时,结果不再是纯数值,而是适合界面展示的自然语言文案:

2000:formatI('human') // 输出 "a few seconds" 2000:formatI('human+') // 输出 "in a few seconds" -2000:formatI('human+') // 输出 "a few seconds ago"

从输出风格看,formatI的人性化文案遵循 humanize-duration 一类库的约定,humanhuman+的差异在于:

  • human:直接输出时长描述,如"a few seconds"(数秒);
  • human+:针对正值附加"未来"语义前缀,输出"in a few seconds"(在几秒后);针对负值附加"过去"语义后缀,输出"a few seconds ago"(几秒前)。

这一特性特别适合倒计时、有效期剩余时间、任务执行耗时等场景。例如"距离任务开始还有几秒"可以这样渲染:

距离开标还有 {d.timeLeft:formatI('human+')}

d.timeLeft为正值时显示"in …",为负值时自动切换为"… ago",模板无需自己判断正负号。

5. 单位换算:通过 patternIn 声明输入单位

当原始数据不是毫秒时,可以通过第二个参数patternIn声明输入单位,formatI会先把输入换算成毫秒,再按patternOut输出:

60:formatI('ms', 'minute') // 输出 3600000 4:formatI('ms', 'weeks') // 输出 2419200000
  • 第一个示例:输入值为60、单位为minute(分钟),先换算为 60 × 60000 = 3600000 毫秒,再以ms(毫秒)输出,结果为3600000
  • 第二个示例:输入值为4、单位为weeks(周),先换算为 4 × 7 × 86400000 = 2419200000 毫秒,再以ms输出,结果为2419200000

这一能力让模板可以直接消费来自不同数据源、不同单位约定的字段:数据库里存的是分钟,就写patternIn = 'minute';表单提交的是周数,就写patternIn = 'weeks',无需在数据入库前预先做单位归一化。

6. 直接解析 ISO 8601 时长字符串

除了纯数值,formatI还能直接解析 ISO 8601 时长字符串(P...T...格式),这是处理跨系统时长数据时非常实用的能力:

'P1M':formatI('ms') // 输出 2628000000 'P1Y2M3DT4H5M6S':formatI('hour') // 输出 10296.085
  • P1M表示 1 个月,按"月 = 365 ÷ 12 天"折算为 30.416666… 天,即 2628000000 毫秒;
  • P1Y2M3DT4H5M6S表示 1 年 2 个月 3 天 4 小时 5 分 6 秒,按"年 = 365 天、月 = 365 ÷ 12 天"折算后以小时输出,结果为 10296.085 小时(即 8760 + 1460 + 72 + 4 + 0.0833… + 0.00166… ≈ 10296.085)。

由此可以推断formatI对非整数单位的折算采用以下基准(与上述官方示例的计算结果完全吻合):

  • 1 年 = 365 天
  • 1 月 = 365 ÷ 12 ≈ 30.4166667 天
  • 1 周 = 7 天
  • 1 天 = 24 小时 = 86400000 毫秒

因此在对"月 / 年"级时长做精确换算时,应留意结果包含小数(如10296.085小时),模板中若需取整展示,可再结合数值格式化器处理。

7. 与日期类格式化器组合的实战场景

formatI与模板打印中的日期格式化器搭配,可以覆盖"起止时间 → 时长 → 可读文案"的完整链路:

  • 计算两个日期的差值再人性化展示:先用diffD求出两个日期之间的毫秒差,再交给formatI输出。diffD默认输出单位为毫秒(详见 日期格式化),其返回值正好可以作为formatI的输入:
{d.endDate:diffD(d.startDate):formatI('human')} // 例如 "a few seconds" {d.endDate:diffD(d.startDate, 'minutes'):formatI('hour')} // 先按分钟求差,再换算为小时
  • 到期提醒文案:用diffD求出"当前时间 - 截止时间"的差值(负值表示已过期),再以formatI('human+')输出,自动得到"还有 X"或"X 之前"的文案;
  • 工期 / 服务时长统计:直接用毫秒字段formatI('days')输出精确到天的时长,或用formatI('hours')输出精确到小时的工时。

由于格式化器支持链式调用(前一个的输出作为后一个的输入),上述组合无需编写脚本,纯模板即可实现。

8. 使用注意事项

  1. 默认输入单位是毫秒:省略patternIn时,数值输入一律按毫秒解析。如果字段实际单位是秒或分钟,务必显式声明patternIn,否则结果会差几个数量级;
  2. patternOut使用字符串字面量:与格式化器常量参数约定一致,格式串建议用单引号包裹,如formatI('seconds')
  3. 月 / 年换算存在小数:ISO 8601 与"月 / 年"单位的折算基于 365 天/年、365÷12 天/月,结果可能为小数,按需配合取整格式化器;
  4. 数值与人性化输出并存:需要参与后续计算时用单位输出(secondhour等),仅需展示时用human/human+,避免把可读文案再喂给数值计算;
  5. 适用版本:本文语法以当前仓库 模板打印文档 及其 安装说明 为准,模板打印为商业插件,使用时请先按官方商业插件激活流程完成激活(Docker 环境如需生成 PDF,还需按 安装文档 安装 LibreOffice)。

综上,formatI以两个参数覆盖了"数值 → 指定单位"、"数值 → 人性化文案"、"指定输入单位 → 毫秒归一"、"ISO 8601 字符串 → 任意单位"四类转换,是 NocoBase 模板打印中处理时长类字段的核心工具,值得在每张涉及时间的单据模板中优先选用。

【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询