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 type time.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:

DescriptionValid 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.

DescriptionValid 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 and CET 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 and PDT (depending on Daylight Savings Time) is America/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-05-19 (string)
{{ $t.UnixMilli }} --> 1716136483050 (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)
Last modified: