Go

How does Go's time layout work (the reference time Mon Jan 2 15:04:05 MST 2006)? What bugs come from using "2006-01-02" vs "YYYY-MM-DD", time zones and time.Parse vs time.ParseInLocation?

Question 534HardGo 1.22 to 1.25

You write a layout by showing how the reference time 01/02 03:04:05PM '06 -0700 would look in your format: 1=month, 2=day, 3/15=hour, 4=minute, 5=second, 6=year, 7=zone. Any text that is not a recognized token is copied through literally. What does this print?

t := time.Date(2024, time.March, 5, 14, 7, 9, 0, time.UTC)
fmt.Println(t.Format("YYYY-MM-DD"))     // YYYY-MM-DD  (no tokens, printed literally)
fmt.Println(t.Format("2006-01-02"))     // 2024-03-05
fmt.Println(t.Format("2006-02-01"))     // 2024-05-03  (day and month swapped)
fmt.Println(t.Format("15:04 03:04PM"))  // 14:07 02:07PM
fmt.Println(t.Format(time.DateOnly))    // 2024-03-05  (Go 1.20 constants)

loc, err := time.LoadLocation("Asia/Kolkata")
if err != nil {
	log.Fatal(err)
}
t1, _ := time.Parse(time.DateTime, "2024-03-05 10:00:00")                // UTC
t2, _ := time.ParseInLocation(time.DateTime, "2024-03-05 10:00:00", loc) // IST
fmt.Println(t1.Equal(t2), t1.Sub(t2)) // false 5h30m0s

Pitfalls:

  • time.Parse treats input that has no zone as UTC. Use ParseInLocation for local wall-clock input.
  • If the input has an abbreviation like "PST", Parse may create a fabricated zone with offset 0 when that abbreviation is not the one used by the current location. Prefer numeric offsets such as time.RFC3339.
  • Using 01 for the hour instead of 15 or 03 is a common bug.
  • LoadLocation fails in minimal containers that have no tzdata. Add import _ "time/tzdata" to embed it.
  • Compare times with Equal, not ==. == also compares the location and the monotonic clock reading.

More on More Standard Library Essentials

All 16 More Standard Library Essentials questions