Custom AM/PM output question on .LastMod.Format

So if I have something like this, it outputs 01:56AM PST

{{ .Lastmod.Format "Jan 02, 2006 at 03:04PM MST" }}

What would be a efficient method to convert AM / PM to a.m. / p.m. like Associated Press style formats require? Been struggling to wrap my head around the best way to do this in a Hugo template.

See the time.Format function.

Does the AP requires dots in the a.m./p.m.? I am afraid you can do that only with some helpers like replace. The time formatting package only allows for a large AM, that you could replace or lowercase in a piped command (like .Lastmod.Format "formatstring" | lower. Golang is a bit inflexible with date formatting.

With this front matter:

date = 2022-01-10T07:46:57-08:00

Code Output Valid
{{ .Date.Format "3:04 PM" }} 7:46 AM :white_check_mark:
{{ .Date.Format "3:04 pm" }} 7:46 am :white_check_mark:
{{ .Date.Format "3:04 p.m." }} 7:46 p.m. :x:

So it’s simple to get lowercase am/pm, but to get the dots…

{{ .Date.Format "3:04 pm" | replaceRE "am" "a.m." | replaceRE "pm" "p.m." }}

With some languages, if your format string includes the full month or full day, the code above will produce undesirable results because the full month or full day may include the string “am”. For example, “January” in Finnish is “tammikuu”. You can handle this with a more precise regex value (the first arg to strings.ReplaceRE).

1 Like

Yes, AP style requires a space then a.m./p.m. which often adds a level of complexity to date/time formatting.

replaceRE looks to be what I was trying to find! Thanks for the suggestion.

Since I’m doing this on a .LastMod, I assume to work around that I could just call the Date and Time separately? Not being a web developer, and just knowing enough about code/ssg’s to be dangerous, the Regex solution would be the correct path, but I’d have to learn how to do that.

But something like {{ .Lastmod.Format "January 02, 2006"}} at {{ .Lastmod.Format "3:04 pm" | replaceRE "am" "a.m." | replaceRE "pm" "p.m." }} should work.

And for Month formatting, AP Style requires some months be abbreviated and some not. Maybe down the road I’ll get under the hood and figure out a more elegant solution, but for now, I could just use replaceRE for the months that need to be abbreviated. "January" "Jan." or is there a far better way to do something like this?

Last Updated: {{ .Lastmod.Format "January 02, 2006" | replaceRE "January" "Jan." | replaceRE "February" "Feb." | replaceRE "August" "Aug." | replaceRE "September" "Sept." | replaceRE "October" "Oct." | replaceRE "November" "Nov."}} at {{ .Lastmod.Format "3:04 pm" | replaceRE "am" "a.m." | replaceRE "pm" "p.m." }}

I’d create a partial to handle this stuff.

layouts/_default/single.html

{{ partial "format-ap-datetime" .Lastmod }}

layouts/partials/format-ap-datetime.html

{{ $this := "layouts/partials/format-ap-datetime.html" }}
{{ $type := printf "%T" . }}
{{ if ne $type "time.Time" }}
  {{ errorf "%q received a parameter of type %q but requires a time.Time value." $this $type }}
{{ end }}

{{ $m := dict
  "January" "Jan."
  "February" "Feb."
  "March" "March"
  "April" "April"
  "May" "May"
  "June" "June"
  "July" "July"
  "August" "Aug."
  "September" "Sep."
  "October" "Oct."
  "November" "Nov."
  "December" "Dec."
}}

{{ $month := .Format "January" }}
{{ $date := .Format "January 02, 2006" | replaceRE $month (index $m $month) }}
{{ $time := .Format "3:04 pm" | replaceRE "am" "a.m." | replaceRE "pm" "p.m." }}

{{ return printf "%s at %s" $date $time }}
2 Likes

Ah, that makes so much more sense!

Thank you @jmooring! For more than the “use a partial” response I was expecting.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.