Hugo 模板函数 time.Duration 完整指南:以时间单位与数值构造时长并调用 Duration 方法
2026/9/19 12:36:03 网站建设 项目流程

Hugo 模板函数 time.Duration 完整指南:以时间单位与数值构造时长并调用 Duration 方法

【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo

time.Duration是 Hugo 模板系统time命名空间下的核心函数,它接收一个时间单位(如hoursecond)和一个数值,返回 Go 标准的time.Duration值,随后即可调用SecondsMinutesHoursDuration方法进行换算与格式化。本文基于 Hugo 当前源码(实现位于 tpl/time/time.go)与该函数的官方文档(docs/content/en/functions/time/Duration.md),完整讲解其签名、单位取值、源码实现原理、与time.ParseDuration的差异,以及在实际模板中的典型用法。

函数签名与返回值

根据文档中声明的签名:

time.Duration TIME_UNIT NUMBER
  • TIME_UNIT:字符串,表示时间单位,支持全称与缩写(见下文单位表);
  • NUMBER:数值,表示该单位的数量,可以是整数或可转换为整数的字符串;
  • 返回值time.Duration,即 Go 标准库time包中的时长类型。

同时该函数注册了别名duration,因此time.Durationduration两种写法等价。别名注册位于 tpl/time/init.go,其中还给出了管道用法示例:

{{ mul 60 60 | duration "second" }} → 1h0m0s

即先计算60 * 60 = 3600,再以second为单位构造时长,得到1h0m0s

支持的合法时间单位

time.Duration的第二个参数(时间单位)必须是下表所列取值之一,包含全称与缩写:

DurationValid time units
hourshourh
minutesminutem
secondsseconds
millisecondsmillisecondms
microsecondsmicrosecondusµs
nanosecondsnanosecondns

其中微秒同时支持 ASCII 缩写us与希腊字母µs两种写法,毫秒、纳秒等则各有一个全称与一个缩写。超出该表的单位(例如复数形式hoursminutes)会被判定为非法,触发错误(详见下文源码解析)。

基础用法示例

文档给出的标准示例——用time.Duration计算一天包含多少秒:

{{ $duration := time.Duration "hour" 24 }} {{ printf "There are %.0f seconds in one day." $duration.Seconds }}

渲染结果为:

There are 86400 seconds in one day.

这里time.Duration "hour" 24构造了 24 小时的时长,随后调用Duration方法Seconds将其换算为秒数(86400),再通过printf%.0f格式化输出,避免浮点数小数点后的尾零。

源码实现原理

time.Duration的底层实现在 tpl/time/time.go,逻辑非常清晰,共分三步:

  1. 单位字符串转换与校验:函数内部维护了一张单位查找表durationUnits,将每个合法单位(全称与缩写)映射到 Go 标准库的时长常量:
var durationUnits = map[string]time.Duration{ "nanosecond": time.Nanosecond, "ns": time.Nanosecond, "microsecond": time.Microsecond, "us": time.Microsecond, "µs": time.Microsecond, "millisecond": time.Millisecond, "ms": time.Millisecond, "second": time.Second, "s": time.Second, "minute": time.Minute, "m": time.Minute, "hour": time.Hour, "h": time.Hour, }
  1. 数值转换:通过cast.ToStringEcast.ToInt64E完成参数类型转换。这意味着数值参数既可以直接传整数,也可以传数字字符串(如"30"),Hugo 会将其转为int64

  2. 乘法构造时长:最终结果由time.Duration(n) * unitDuration计算得出,即数值乘以单位对应的时长常量。

从源码结构看,time.Duration本质上是「单位查表 + 数值转换 + 标量乘法」的封装,不涉及任何时间基准(如当前时刻或时区),因此它是一个纯函数式的换算工具。

错误处理与边界

当传入非法单位时,函数返回错误:

"%q" is not a valid duration unit

例如传入复数形式hours(不在表中)就会触发该错误;tpl/time/time_test.go中的TestDuration用例(tpl/time/time_test.go)明确验证了这一行为,其中{"hours", 20, false}一项断言了非法单位必须返回 error。同一测试还覆盖了全称/缩写/µs变体与字符串数值({"hour", "30", 30 * time.Hour})等 15 组场景,可作为理解函数行为的参考。

与 time.ParseDuration 的对比

time命名空间还提供另一个构造时长的函数time.ParseDuration(文档见 docs/content/en/functions/time/ParseDuration.md,实现见 tpl/time/time.go)。二者都返回time.Duration,但适用场景不同:

维度time.Durationtime.ParseDuration
入参形式独立的单位参数 + 数值参数单个时长字符串,如"300ms""-1.5h""2h45m"
是否支持组合不支持,一次只能指定一种单位支持,可混合多种单位(如2h45m
是否支持负数/小数数值可为负(源码未限制),但单位单一支持带符号与小数,如-1.5h
实现方式查表乘法直接调用 Go 标准库time.ParseDuration

典型场景:若数据源分别给出「单位」和「数量」两个字段(例如配置项拆分为unit: hourvalue: 24),用time.Duration更自然;若数据源直接给出一段可读时长字符串,则用time.ParseDuration更直接。

Duration 方法:让返回值发挥作用

time.Duration的返回值可以调用Duration命名空间下的全部方法(方法清单见 docs/content/en/methods/duration/_index.md),包括:

  • Seconds:返回以秒计的浮点数(float64),示例见 docs/content/en/methods/duration/Seconds.md,例如time.ParseDuration "3.5h2.5m1.5s".Seconds结果为12751.5
  • MinutesHours:分别返回以分钟、小时计的浮点数;
  • MillisecondsMicrosecondsNanoseconds:返回对应粒度的整数值;
  • Abs:返回绝对值的time.Duration
  • RoundTruncate:按指定时长粒度进行舍入与截断。

这些方法同样适用于time.Duration的返回值,例如开篇示例中的$duration.Seconds

实际应用:模板中的典型场景

在真实站点模板中,time.Duration常用于把「数值 + 单位」形式的配置转换为可读时长或进行跨单位换算。例如,从站点参数读取缓存过期时长并格式化为秒:

{{ $ttlValue := site.Params.cacheTTL.value | default 30 }} {{ $ttlUnit := site.Params.cacheTTL.unit | default "minute" }} {{ $ttl := time.Duration $ttlUnit $ttlValue }} {{ printf "Cache TTL is %.0f seconds (%v)." $ttl.Seconds $ttl }}

或将时长精确格式化到小时:

{{ $d := time.Duration "minute" 90 }} {{ printf "%v" $d }} <!-- 1h30m0s --> {{ printf "%.1f hours" $d.Hours }} <!-- 1.5 hours -->

需要强调的是,time.Duration只负责「构造时长」,不涉及具体时间点;若需要结合当前时刻或特定时区做日期运算,应搭配time.Nowtime.AsTimetime.In(实现同见 tpl/time/time.go)等函数使用。

小结

time.Duration以极简的「单位 + 数值」二元入参,复用了 Go 标准库的时长体系,为 Hugo 模板提供了清晰、可读的时长构造方式。理解其单位表(含µs变体)、非法单位报错行为以及与time.ParseDuration的分工,能帮助你在模板中写出既准确又易维护的时间换算代码。

【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo

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

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

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

立即咨询