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.Time
value, 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.Time
value 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
date
data 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.Time
and 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 2006
Create 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
PST
andCET
are not time zones. They are time zone abbreviations.Strings such as
-07:00
and+01:00
are 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
PST
andPDT
(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" }} --> 2024-12-17 (string)
{{ $t.UnixMilli }} --> 1734447783464 (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.Time
value 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)