go 44 lines · 7 steps

Parsing and formatting dates in Go

A small package that normalizes messy date strings using Go's reference-time layout system.

Explained by highlit
1package dateutil
2 
3import (
4 "fmt"
5 "time"
6)
7 
8const (
9 isoDate = "2006-01-02"
10 usDateTime = "01/02/2006 3:04 PM"
11 rfc3339 = time.RFC3339
12)
13 
14func NormalizeToISO(raw string) (string, error) {
15 layouts := []string{rfc3339, usDateTime, isoDate, "2006-01-02 15:04:05"}
16 
17 for _, layout := range layouts {
18 if t, err := time.Parse(layout, raw); err == nil {
19 return t.Format(isoDate), nil
20 }
21 }
22 return "", fmt.Errorf("unrecognized date format: %q", raw)
23}
24 
25func ParseInLocation(raw, zone string) (time.Time, error) {
26 loc, err := time.LoadLocation(zone)
27 if err != nil {
28 return time.Time{}, fmt.Errorf("invalid timezone %q: %w", zone, err)
29 }
30 return time.ParseInLocation(usDateTime, raw, loc)
31}
32 
33func FormatFriendly(t time.Time) string {
34 return t.Format("Mon, Jan 2 2006 at 3:04 PM MST")
35}
36 
37func DaysUntil(deadline string) (int, error) {
38 t, err := time.Parse(isoDate, deadline)
39 if err != nil {
40 return 0, err
41 }
42 d := time.Until(t)
43 return int(d.Hours() / 24), nil
44}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Go encodes date layouts as the reference time Mon Jan 2 15:04:05 MST 2006, not with format tokens.
  2. 2Trying a list of candidate layouts lets you accept several input formats and reject the rest cleanly.
  3. 3Wrapping parse errors with %w preserves the underlying cause for callers that inspect it.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Parsing and formatting dates in Go — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code