Working with time
Overview
Hugo uses Go’s time package to convert, format, localize, parse, compare, and manipulate dates and times.
Date and time are not separate entities. Combined they are a
time.Timevalue, representing month, day, year, hour, minute, second, fractional seconds, and time zone offset from Coordinated Universal Time (UTC).
For each content page you can set up to four predefined date values:
- date
- Typically the creation date.
- publishDate
- When to publish the content.
- expiryDate
- When the content should expire (unpublish).
- lastmod
- When the content was last modified.
Your Markdown might look like this:
---
title: About
draft: false
date: 2022-01-01T17:39:56-08:00
publishDate: 2022-02-01T08:00:00-08:00
expiryDate: 2023-02-01T08:00:00-08:00
lastmod: 2022-01-28T17:37:06-08:00
---Regardless of front matter format (JSON, TOML, or YAML), Hugo casts these entries to time.Time values when it parses the front matter.
If you create custom date fields in your front matter, and your front matter uses JSON or YAML, Hugo will read the custom date as a string value. You must convert the string to a
time.Timevalue before you convert, format, localize, parse, compare, or manipulate the values. Please see the first example below.With TOML, date values are first-class citizens. TOML has a
datedata type while JSON and YAML do not. When you add a custom date field to your TOML front matter, the value is already of typetime.Timeand does not require conversion.
Examples
Time
Convert
Convert a string representation of a time to a time.Time value.
{{ $t := "2023-01-27T23:44:58-08:00" }}
{{ $t = time.AsTime $t }}
{{ $t }} --> 2023-01-27 23:44:58 -0800 PST (time.Time)Format
Format a time.Time value based on Go’s reference time:
Mon Jan 2 15:04:05 MST 2006Create a format string using these components:
| Description | Valid components |
|---|---|
| Year | "2006" "06" |
| Month | "Jan" "January" "01" "1" |
| Day of the week | "Mon" "Monday" |
| Day of the month | "2" "_2" "02" |
| Day of the year | "__2" "002" |
| Hour | "15" "3" "03" |
| Minute | "4" "04" |
| Second | "5" "05" |
| AM/PM mark | "PM" |
| Time zone offsets | "-0700" "-07:00" "-07" "-070000" "-07:00:00" |
Replace the sign in the format string with a Z to print Z instead of an offset for the UTC zone.
| Description | Valid components |
|---|---|
| Time zone offsets | "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 (string)Strings such as
PSTandCETare not time zones. They are time zone abbreviations.Strings such as
-07:00and+01:00are not time zones. They are time zone offsets.A time zone is a geographic area with the same local time. For example, the time zone abbreviated by
PSTandPDT(depending on Daylight Savings Time) isAmerica/Los_Angeles.
Localize
Localize a time.Time value to the site’s language and region. The valid format tokens are:
:date_short:date_medium:date_long:date_full:time_short:time_medium:time_long:time_full
The locale (language and region) of this example is en-US:
{{ $t := "2023-01-27T23:44:58-08:00" }}
{{ $t = time.AsTime $t }}
{{ $t | time.Format ":date_short" }} --> 1/27/23 (string)
{{ $t | time.Format ":date_medium" }} --> Jan 27, 2023 (string)
{{ $t | time.Format ":date_long" }} --> January 27, 2023 (string)
{{ $t | time.Format ":date_full" }} --> Friday, January 27, 2023 (string)
{{ $t | time.Format ":time_short" }} --> 11:44 pm (string)
{{ $t | time.Format ":time_medium" }} --> 11:44:58 pm (string)
{{ $t | time.Format ":time_long" }} --> 11:44:58 pm PST (string)
{{ $t | time.Format ":time_full" }} --> 11:44:58 pm Pacific Standard Time (string)Parse
Parse a time.Time value.
{{ $t := "2023-01-27T23:44:58-08:00" }}
{{ $t = time.AsTime $t }}
{{ $t.Year }} --> 2023 (int)
{{ $t.Month }} --> January (time.Month)
{{ $t.Month.String }} --> January (string)
{{ $t.Day }} --> 27 (int)
{{ $t.Hour }} --> 23 (int)
{{ $t.Minute }} --> 44 (int)
{{ $t.Second }} --> 58 (int)
{{ $t.Nanosecond }} --> 0 (int)
{{ $t.Weekday }} --> Friday (time.Weekday)
{{ $t.Weekday.String }} --> Friday (string)
{{ $t.YearDay }} --> 27 (int)
{{ $t.Unix }} --> 1674891898 (int64)
{{ $t.UnixMilli }} --> 1674891898000 (int64)
{{ $t.UnixMicro }} --> 1674891898000000 (int64)
{{ $t.UnixNano }} --> 1674891898000000000 (int64)
{{ $t.String }} --> 2023-01-27 23:44:58 -0800 PST (string)
{{ $t.UTC }} --> 2023-01-28 07:44:58 +0000 UTC (time.Time)
{{ $t.Local }} --> 2023-01-27 23:44:58 -0800 PST (time.Time)The last two examples return time.Time values, so you can chain methods.
{{ $t.UTC.Hour }} --> 7 (int)
{{ $t.Local.Month }} --> January (time.Month)To convert the month or weekday to an integer:
{{ $t.Month | int }} --> 1 (int)
{{ $t.Weekday | int }} --> 5 (int)Current time
Get the current time, then format or parse as described above.
{{ $t := time.Now }}
{{ $t.Format "2006-01-02" }} --> 2025-10-31 (string)
{{ $t.UnixMilli }} --> 1761956490519 (int64)DST and zero
Test for Daylight Savings Time (DST) and zero dates.
{{ $t1 := time.AsTime "2023-01-01T00:00:00-08:00" }}
{{ $t2 := time.AsTime "2023-07-01T00:00:00-07:00" }}
{{ $t3 := time.AsTime "0001-01-01T00:00:00-00:00" }}
{{ $t1.IsDST }} --> false (bool)
{{ $t2.IsDST }} --> true (bool)
{{ $t1.IsZero }} --> false (bool)
{{ $t3.IsZero }} --> true (bool)Compare
Compare two time.Time values.
{{ $t1 := time.AsTime "2023-01-01T17:00:00-08:00" }}
{{ $t2 := time.AsTime "2030-01-01T17:00:00-08:00" }}
{{ $t3 := time.AsTime "2010-01-01T17:00:00-08:00" }}
{{ $t4 := time.AsTime "2023-01-01T20:00:00-05:00" }}
{{ $t1.Before $t2 }} --> true (bool)
{{ $t1.After $t3 }} --> true (bool)
{{ $t1.Equal $t4 }} --> true (bool)Add years, months, days
Add years, months, and days to a time.Time value.
{{ $t := "2023-01-27T23:44:58-08:00" }}
{{ $t = time.AsTime $t }}
{{ $t.AddDate 0 0 1 }} --> 2023-01-28 23:44:58 -0800 PST (time.Time)
{{ $t.AddDate 0 1 1 }} --> 2023-02-28 23:44:58 -0800 PST (time.Time)
{{ $t.AddDate 1 1 1 }} --> 2024-02-28 23:44:58 -0800 PST (time.Time)
{{ $t.AddDate -1 -1 -1 }} --> 2021-12-26 23:44:58 -0800 PST (time.Time)When adding months or years, Go normalizes the
time.Timevalue if the resulting day does not exist. For example, adding one month to 31 January produces 2 March or 3 March, depending on the year.See this explanation from the Go team.
Duration
Parse, round, truncate
Parse, round, and truncate a time.Duration value.
{{ $d := "3.5h2.5m1.5s" }}
{{ $d = time.ParseDuration $d }}
{{ $d }} --> 3h32m31.5s (time.Duration)
{{ $d.Hours }} --> 3.5420833333333333 (float64)
{{ $d.Minutes }} --> 212.525 (float64)
{{ $d.Seconds }} --> 12751.5 (float64)
{{ $d.Milliseconds }} --> 12751500 (int64)
{{ $d.Microseconds }} --> 12751500000 (int64)
{{ $d.Nanoseconds }} --> 12751500000000 (int64)
{{ $d.String }} --> 3h32m31.5s (string)
{{ $d.Round (time.ParseDuration "2h") }} --> 4h0m0s (time.Duration)
{{ $d.Round (time.ParseDuration "3m") }} --> 3h33m0s (time.Duration)
{{ $d.Round (time.ParseDuration "4s") }} --> 3h32m32s (time.Duration)
{{ $d.Truncate (time.ParseDuration "2h") }} --> 2h0m0s (time.Duration)
{{ $d.Truncate (time.ParseDuration "3m") }} --> 3h30m0s (time.Duration)
{{ $d.Truncate (time.ParseDuration "4s") }} --> 3h32m28s (time.Duration)Absolute value
Get the absolute value of a time.Duration value.
{{ $d := "-3h" }}
{{ $d = time.ParseDuration $d }}
{{ $d }} --> -3h0m0s (time.Duration)
{{ $d.Abs }} --> 3h0m0s (time.Duration)Add or subtract
Add or subtract a duration from a time.Time value.
{{ $t := "2023-01-27T23:44:58-08:00" }}
{{ $t = time.AsTime $t }}
{{ $d1 := "3h20m10s" }}
{{ $d1 = time.ParseDuration $d1 }}
{{ $d2 := "-3h20m10s" }}
{{ $d2 = time.ParseDuration $d2 }}
{{ $t.Add $d1 }} --> 2023-01-28 03:05:08 -0800 PST (time.Time)
{{ $t.Add $d2 }} --> 2023-01-27 20:24:48 -0800 PST (time.Time)Calculate duration
Calculate the duration between two time.Time values.
{{ $t1 := time.AsTime "2023-01-27T23:44:58-08:00" }}
{{ $t2 := time.AsTime "2023-01-26T22:34:38-08:00" }}
{{ $t1.Sub $t2 }} --> 25h10m20s (time.Duration)Create a duration
Create a duration from a time unit and integer. This method is similar to time.ParseDuration.
{{ time.Duration "h" 2 }} --> 2h0m0s (time.Duration)
{{ time.Duration "m" 2 }} --> 2m0s (time.Duration)
{{ time.Duration "s" 2 }} --> 2s (time.Duration)