Skip to content
Go Basics: Parse Timestamps and Durations Explicitly

Go Basics: Parse Timestamps and Durations Explicitly

October 31, 2026

A timestamp with an offset describes an instant; a duration describes elapsed time. Parse both explicitly before computing a deadline, and reject invalid calendar dates.

Prepare a scratch directory

Tested on Linux amd64 with Go 1.26.10. Install Go and make go available on PATH. You also need Bash, a text editor, and the standard mktemp, rm, and rmdir utilities. The example uses only the standard library and needs no module or external dependency.

Keep the same terminal open. Stop if setup fails, before saving the source:

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

Run the example

Save this as time-layouts-demo.go:

package main

import (
	"fmt"
	"time"
)

func main() {
	started, err := time.Parse(time.RFC3339, "2026-10-31T09:30:00+09:00")
	if err != nil {
		panic(err)
	}
	timeout, err := time.ParseDuration("1h30m")
	if err != nil {
		panic(err)
	}
	fmt.Println("UTC:", started.UTC().Format(time.RFC3339))
	fmt.Println("Deadline:", started.Add(timeout).UTC().Format(time.RFC3339))
	fmt.Println("Elapsed minutes:", timeout.Minutes())
	_, err = time.Parse("2006-01-02", "2026-02-30")
	fmt.Println("Invalid date rejected:", err != nil)
}

Run it:

go run time-layouts-demo.go

Observed output:

UTC: 2026-10-31T00:30:00Z
Deadline: 2026-10-31T02:00:00Z
Elapsed minutes: 90
Invalid date rejected: true

Read the result

Go layouts use a reference date rather than strftime-style directives. RFC3339 is a predefined layout for the offset-bearing timestamp. UTC normalization changes its representation without changing the instant. The impossible February date is rejected rather than silently normalized.

Apply it carefully

A fixed numeric offset does not carry a region’s daylight-saving rules. Use a named location for regional scheduling. Adding 24 hours is elapsed-time arithmetic and can differ from adding one calendar day across a clock change. ParseDuration does not accept a day unit; keep these concepts separate.

The official Go reference documents the behavior used here.

Clean up

Remove the saved source, return to the starting directory, and remove the empty practice directory. go run does not leave an executable here; Go manages its build cache separately.

rm -- time-layouts-demo.go
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

If the directory is not empty, inspect its remaining contents before removing anything else.

Acknowledgements

This post was created with assistance from AI.

Last updated on