Hugo 模板中的 TIME.Day 方法:从 time.Time 提取「日」并正确处理时区
2026/9/20 2:49:55 网站建设 项目流程
  • 开发工具
  • 前端
  • CLI

【免费下载链接】hugo

The world’s fastest framework for building websites.

项目地址:https://gitcode.com/gh_mirrors/hu/hugo
点击查看免费下载

本篇指南讲解 Hugo 模板方法Day——对一个time.Time值调用后返回该时间点所在月份的「日」(1–31 的整数),常用于日期归档、按日分组统计、日粒度视图等场景。读完本文,你将掌握Day的完整调用方式、与其配套的time.AsTime字符串转时间用法、时区对结果的影响,以及它背后的 Go 标准库实现原理。

方法签名与返回值

Daytime.Time类型的方法,签名如下(见 docs/content/en/methods/time/Day.md 的 front matter 声明):

  • 签名TIME.Day
  • 返回类型int(该月中的第几天,取值范围 1–31)

它不接受任何参数,调用方式是对任意time.Time值直接以点号调用。

基本用法

文档给出的最小示例(Day.md):

{{ $t := time.AsTime "2023-01-27T23:44:58-08:00" }} {{ $t.Day }} → 27

这里先用time.AsTime把 RFC3339 格式的时间字符串解析成time.Time值,再通过$t.Day取出「日」。对2023-01-27T23:44:58-08:00这个时间点,结果是27

配套函数 time.AsTime

time.AsTime是 Hugo 在time命名空间下提供的解析函数,实现在 tpl/time/time.go:

func (ns *Namespace) AsTime(v any, args ...any) (any, error) { loc := ns.location if len(args) > 0 { locStr, err := cast.ToStringE(args[0]) if err != nil { return nil, err } loc, err = time.LoadLocation(locStr) if err != nil { return nil, err } } return htime.ToTimeInDefaultLocationE(v, loc) }

要点:

  • 第一个参数可以是字符串、time.Time或其他可被cast转换的值;
  • 可选的第二个参数用于指定 IANA 时区名(如"America/New_York""Asia/Shanghai"),不传时使用 Hugo 的默认时区(即站点timezone配置);
  • 底层调用htime.ToTimeInDefaultLocationE,该函数(见 common/htime/time.go)会优先识别实现了AsTimeProvider接口的值(例如 go-toml 解析出的LocalDate/LocalDateTime),对time.Time则先格式化为 RFC3339 字符串再交给cast.ToTimeInDefaultLocationE统一处理。

直接使用已解析的时间值

除了字符串,凡是模板里已经存在的time.Time值都可以直接调用Day,无需先经过time.AsTime。例如配合time.Now

{{ $t := time.Now }} {{ $t.Day }} → 当前日期的「日」

或直接对页面参数中的日期取值:

{{ with .Params.date }} {{ .Day }} {{ end }}

时区对 Day 结果的影响

Day返回的是时间值在其所在时区上下文中的「日」。同一个 UTC 时间点,在不同时区下可能落到不同的「日」。例如2023-01-27T23:44:58-08:00等价于2023-01-28T07:44:58Z

  • 在 UTC(或-08:00以东的时区)下,Day返回28
  • -08:00时区本身,Day返回27

因此,当需要以「日」为单位统计或展示时,务必先确定统一的时区基准。可以通过time.AsTime的第二个参数、站点配置的timezone,或time.In方法(见 tpl/time/time.go)来转换时区:

{{ $t := time.AsTime "2023-01-27T23:44:58-08:00" }} {{ $t.In "Asia/Shanghai" | .Day }} → 28

提示:time.In内部使用带缓存的分区(dynacache)加载 IANA 时区,避免重复解析开销,见 tpl/time/time.go。

边界与注意事项

  • 返回值始终是 int:可直接参与数值运算或比较,无需再转换;
  • 月份最后一天31是最大值,小于 31 的月份最后一天(如302829)按该月实际天数返回;
  • 零值时间:Go 的零值time.Time0001-01-01)调用Day返回1,空字符串解析失败会报错,模板渲染时需用withdefault兜底;
  • time.Format的差异Day返回结构化整数便于运算;若只需展示两位数字(如0127),可用time.Format "02"printf "%02d"

与同系列方法的关系

Day属于 Hugo 文档中Time methods系列(见 docs/content/en/methods/time/_index.md),同系列还包括MonthYearHourMinuteSecondWeekdayYearDay等,全部来自 Go 标准库time.Time的方法集,因此行为与 Go 完全一致。例如Month返回time.Month类型,可继续调用.String或通过| int转为整数(见 Month.md);YearDay返回当年第几天。组合使用这些方法,可以构建完整的日期维度分析:

{{ $t := time.AsTime "2023-01-27T23:44:58-08:00" }} {{ $t.Year }} → 2023 {{ $t.Month | int }} → 1 {{ $t.Day }} → 27 {{ $t.Weekday.String }} → Friday {{ $t.YearDay }} → 27

典型实战场景

按「日」归档列表:从页面时间中提取日值用于归档分组或排序展示:

{{ $posts := site.RegularPages }} {{ $byDay := $posts.GroupByDate "2006-01-02" }} {{ range $byDay }} <h2>{{ .Key }}</h2> {{ range .Pages }} <a href="{{ .RelPermalink }}">{{ .Title }}</a> {{ end }} {{ end }}

日粒度标签或徽标

<span class="badge">{{ .Date.Day }}</span>

条件判断(例如每月 15 日前的文章加标记):

{{ if le .Date.Day 15 }} <span>上半月发布</span> {{ end }}

小结

Day是 Hugo 模板中获取时间「日」的最直接方法,配合time.AsTimetime.In以及站点时区配置可以精确控制时区语义。其返回值遵循 Go 标准库time.Time.Day的语义,行为稳定可预测,适合在日期归档、按日统计与条件渲染等场景中使用。更多相关方法可继续阅读 Time methods 索引 及同目录下的各方法文档。

  • 开发工具
  • 前端
  • CLI

【免费下载链接】hugo

The world’s fastest framework for building websites.

项目地址:https://gitcode.com/gh_mirrors/hu/hugo
点击查看免费下载

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

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

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

立即咨询