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
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Go encodes date layouts as the reference time Mon Jan 2 15:04:05 MST 2006, not with format tokens.
- 2Trying a list of candidate layouts lets you accept several input formats and reject the rest cleanly.
- 3Wrapping parse errors with %w preserves the underlying cause for callers that inspect it.
Related explainers
go
package theme import ( "fmt"
Per-tenant HTML templates with Gin's renderer
multi-tenancy
concurrency
html-templates
Advanced
8 steps
go
package auth import ( "net/http"
Setting and reading secure session cookies in Go
cookies
session-management
security
Intermediate
6 steps
go
package middleware import ( "net/http"
A maintenance-mode gate in Gin
middleware
atomic-flag
concurrency
Intermediate
8 steps
go
func ServeVideo(c *gin.Context) { id := c.Param("id") video, err := videoRepo.FindByID(c.Request.Context(), id) if err != nil {
Streaming video files with Gin
http streaming
range requests
file serving
Intermediate
6 steps
go
package handler type LineItem struct { SKU string `json:"sku" binding:"required,alphanum"`
Structured validation errors in Gin
validation
json-binding
error-handling
Intermediate
8 steps
go
package deepcopy import ( "bytes"
Deep copying any value with gob in Go
deep-copy
serialization
generics
Intermediate
6 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/parsing-and-formatting-dates-in-go-explained-go-bed0/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.