ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Hugo time.Format 函数完全指南:日期时间格式化、时区与本地化实战

Hugo time.Format 函数完全指南:日期时间格式化、时区与本地化实战 Hugo time.Format 函数完全指南日期时间格式化、时区与本地化实战【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugoHugo 模板中的time.Format函数用于把time.Time值或可解析的日期/时间字符串按照自定义布局或本地化标记格式化为字符串输出。本指南将围绕该函数在 Hugo 项目中的实际应用场景完整讲解其基本用法、时区优先级、Go 参考时间布局、本地化令牌与源码级实现原理帮助你在站点模板中精确控制日期时间的显示效果。函数签名与别名根据 docs/content/en/functions/time/Format.md 中的 front matter 定义签名time.Format LAYOUT INPUT返回类型string别名dateFormat别名注册位于 tpl/time/init.go模板中可直接使用dateFormat{{ dateFormat Monday, Jan 2, 2006 2015-01-21 }} → Wednesday, Jan 21, 2015该映射由ns.AddMethodMapping(ctx.Format, []string{dateFormat}, ...)注册同时保留了time.Format的正式名称。基本用法配合 time.Time 值使用先通过time.AsTime把字符串转换为time.Time再交给time.Format{{ $t : time.AsTime 2023-10-15T13:18:50-07:00 }} {{ time.Format 2 Jan 2006 $t }} → 15 Oct 2023配合可解析的字符串使用time.Format内部会先尝试把输入值转换为time.Time见下文源码解析因此可以直接传入字符串{{ $t : 15 Oct 2023 }} {{ time.Format January 2, 2006 $t }} → October 15, 2023管道写法{{ .Date | time.Format January 2, 2006 }}Hugo 的页面变量如.Date、.Lastmod本身就是time.Time值可以直接传入。可解析的日期/时间字符串格式以下格式摘自 docs/content/en/_common/parsable-date-time-strings.md都可以直接作为time.Format的输入格式时区2023-10-15T13:18:50-07:00America/Los_Angeles2023-10-15T13:18:50-0700America/Los_Angeles2023-10-15T13:18:50ZEtc/UTC2023-10-15T13:18:50默认Etc/UTC2023-10-15默认Etc/UTC15 Oct 2023默认Etc/UTC后三个示例没有完全限定时区将默认使用Etc/UTC时区。时区确定顺序原文档明确指出时区的确定遵循以下优先级日期/时间字符串中自带的时区偏移如-07:00、Z项目配置中指定的timeZoneEtc/UTC时区在 Hugo 源码中该配置字段定义于 config/allconfig/allconfig.go 的TimeZone string并在 config/allconfig/allconfig.go 中传给每个语言配置。配置文件示例hugo.tomltimeZone America/Los_Angeles若模板中传入的时间字符串带有时区偏移则偏移优先于配置否则使用配置的timeZone两者都没有时才回退到Etc/UTC。布局字符串Layout stringtime.Format的布局基于 Go 的参考时间Mon Jan 2 15:04:05 MST 2006布局组件摘自 docs/content/en/_common/time-layout-string.md描述有效组件年2006 06月Jan January 01 1星期Mon Monday日月内2 _2 02日年内__2 002时15 3 03分4 04秒5 05上午/下午标记PM时区偏移-0700 -07:00 -07 -070000 -07:00:00若希望 UTC 时区输出Z而非偏移量可将布局中的符号替换为Z描述有效组件时区偏移Z 形式Z0700 Z07:00 Z07 Z070000 Z07:00:00组合示例{{ $t : 2023-01-27T23:44:58-08:00 }} {{ $t time.AsTime $t }} {{ $t $t.Format Jan 02, 2006 3:04 PM Z07:00 }} {{ $t }} → Jan 27, 2023 11:44 PM -08:00时区缩写与时区偏移的区别原文档特别强调了两点易混淆的概念字符串如PST、CET不是时区而是时区缩写abbreviations字符串如-07:00、01:00不是时区而是时区偏移offsets时区是拥有相同本地时间的地理区域。例如PST与PDT视夏令时而定所对应的时区是America/Los_Angeles本地化Localization使用time.Format可以为当前语言和区域本地化time.Time值。有两种方式方式一直接使用本地化令牌{{ .Date | time.Format :date_medium }} → Jan 27, 2023方式二使用布局字符串布局字符串同样支持本地化。原理是Hugo 先把time.Time按布局格式化再将英文的月份/星期名称替换为本地化名称见下文源码解析。本地化令牌及示例结果本地化为 en-US美国英语令牌结果:date_fullFriday, January 27, 2023:date_longJanuary 27, 2023:date_mediumJan 27, 2023:date_short1/27/23:time_full11:44:58 pm Pacific Standard Time:time_long11:44:58 pm PST:time_medium11:44:58 pm:time_short11:44 pm本地化为 de-DE德语令牌结果:date_fullFreitag, 27. Januar 2023:date_long27. Januar 2023:date_medium27.01.2023:date_short27.01.23:time_full23:44:58 Nordamerikanische Westküsten-Normalzeit:time_long23:44:58 PST:time_medium23:44:58:time_short23:44locale 配置与语言回退日期、货币、数字和百分比的本地化由bep/golocales包执行。Hugo 使用locale配置确定区域设置若未设置则回退到语言键本身解析结果必须是该包支持的 locale详见 docs/content/en/_common/functions/locales.md。源码级实现原理Format 方法先转换后格式化核心实现在 tpl/time/time.gofunc (ns *Namespace) Format(layout string, v any) (string, error) { t, err : htime.ToTimeInDefaultLocationE(v, ns.location) if err ! nil { return , err } return ns.timeFormatter.Format(t, layout), nil }关键点输入v为any类型统一经htime.ToTimeInDefaultLocationE转换为time.Time转换时使用ns.location即项目配置的时区作为默认位置这正是配置时区优先于Etc/UTC的实现基础转换支持多种输入形态AsTimeProvider如 go-toml 的LocalDate/LocalDateTime、time.Time会先格式化为 RFC3339 再交给cast包、以及普通字符串/时间戳TimeFormatter自定义布局与本地化替换本地化替换逻辑位于 common/htime/time.gofunc (f TimeFormatter) Format(t time.Time, layout string) string { if layout { return } if layout[0] : { // It may be one of Hugos custom layouts. switch strings.ToLower(layout[1:]) { case date_full: return f.ltr.FormatDateFull(t) // ... date_long / date_medium / date_short // ... time_full / time_long / time_medium / time_short } } s : t.Format(layout) monthIdx : t.Month() - 1 dayIdx : t.Weekday() if strings.Contains(layout, January) { s strings.ReplaceAll(s, longMonthNames[monthIdx], f.ltr.MonthsWide()[monthIdx]) } else if strings.Contains(layout, Jan) { s strings.ReplaceAll(s, shortMonthNames[monthIdx], f.ltr.MonthsAbbreviated()[monthIdx]) } if strings.Contains(layout, Monday) { s strings.ReplaceAll(s, longDayNames[dayIdx], f.ltr.WeekdaysWide()[dayIdx]) } else if strings.Contains(layout, Mon) { s strings.ReplaceAll(s, shortDayNames[dayIdx], f.ltr.WeekdaysAbbreviated()[dayIdx]) } return s }这段代码印证了两个实现事实以:开头的布局被识别为 Hugo 自定义本地化令牌直接调用bep/golocales翻译器的FormatDateFull、FormatTimeShort等方法普通布局字符串先由 Go 标准库time.Format格式化再把英文月份名January/Jan和星期名Monday/Mon替换为当前 locale 对应的翻译空布局返回空字符串Namespace 的构造依赖time命名空间通过 tpl/time/time.go 的New构造接收htime.TimeFormatter携带 locale 翻译器、*time.Location默认时区和deps.Deps并使用dynacache缓存时区加载结果/tmpl/time/in分区ClearNever策略用于time.In等函数。测试验证common/htime/time.go 中的英文名称切片与替换逻辑在 tpl/time/time_test.go 中有完整测试覆盖可验证以下行为自定义布局与字符串输入{Monday, Jan 2, 2006, 2015-01-21, Wednesday, Jan 21, 2015}非日期布局字符串原样返回{This isnt a date layout string, 2015-01-21, This isnt a date layout string}RFC3339 与 RFC1123 格式互转本地化令牌{:date_medium, 2015-01-21, Jan 21, 2015}时区感知使用America/Los_Angeles时time.Format(:time_full, 2020-03-09T11:00:00)输出11:00:00 am Pacific Daylight Time对应 Issue #9084实战组合示例博客文章页面的日期展示time datetime{{ .Date | time.Format 2006-01-02T15:04:05Z07:00 }} {{ .Date | time.Format January 2, 2006 }} /time多语言站点按 locale 输出{{ if eq site.Language.LanguageCode de-DE }} p{{ .Date | time.Format :date_long }}/p {{ else }} p{{ .Date | time.Format January 2, 2006 }}/p {{ end }}首页最后更新时间提示pLast updated: {{ .Lastmod | time.Format 2 Jan 2006 15:04 MST }}/p小结time.Format是 Hugo 模板中处理日期时间输出的核心函数它接受time.Time值或可解析字符串遵循字符串偏移 项目timeZone配置 Etc/UTC的时区优先级布局基于 Go 参考时间Mon Jan 2 15:04:05 MST 2006以:开头的本地化令牌如:date_medium、:time_full可输出贴合当前 locale 的语言化结果。理解其源码实现转换→格式化→本地化替换后你可以在多语言与多时区场景下精准掌控日期时间的呈现。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表