How to parse a RFC3339 timestamp in Go

Avatar of the author Willem Schots
22 Dec, 2023
~2 min.
RSS

The RFC3339 standard is a popular way to format timestamps on the internet. RFC3339 timestamps:

  • Are human readable.
  • Represent instants in time. No intervals.
  • Are in UTC time or include an UTC offset. No local time.
  • Allow for different precision levels, from years to fractions of a second.
  • Use the YYYY-MM-DD format. No confusion between MM-DD-YYYY or DD-MM-YYYY formats.
  • Are string sortable when every timestamps use consistent time zone information and precision.

This makes it a very pragmatic format.

RFC3339 is a tailored version of the broader ISO8601 standard. It’s not entirely a subset, but it’s pretty close.

RFC3339 in Go’s time package

The Go time package includes two constants that that define appropriate reference layouts for RFC3339 timestamps:

RFC3339     = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"

If we pass these to the time.Parse function we can parse RFC3339 formatted timestamps into time.Time values.

However, not every valid RFC3339 timestamp can be parsed this way:

  • Go expects RFC3339 timestamps to always contain the capital T character, the standard allows for lower case or a space.
  • The standard allows for leap seconds, the time does not deal with them.
main.go
package main

import (
	"fmt"
	"log"
	"time"
)

func main() {
	timestamps := []string{
		"2023-12-22T16:25:33Z",
		"2023-12-22T16:25:33.8Z",
		"2023-12-22T16:25:33.85Z",
		"2023-12-22T16:25:33.855Z",
		"2023-12-22T16:25:33.855873Z",
		"2023-12-22T17:25:33+01:00",
		"2023-12-22T17:25:33.855+01:00",
		"2023-12-22T17:25:33.855873+01:00",
	}

	for i, ts := range timestamps {
		t, err := time.Parse(time.RFC3339, ts)
		if err != nil {
			log.Fatalf("%d: %v", i, err)
		}

		fmt.Println(t)
	}
}
🎓

Subscribe to my Newsletter and Keep Learning.

Gain access to more content and get notified of the latest articles:

I send emails every 1-2 weeks and will keep your data safe. You can unsubscribe at any time.

Hello! I'm the Willem behind willem.dev

I created this website to help new Go developers, I hope it brings you some value! :)

You can follow me on Twitter/X, LinkedIn or Mastodon.

Thanks for reading!