Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

at

Timestamps with millisecond precision, for data that gets stored and compared as text.

Go's time.Time marshals with nanosecond precision and a variable-length fraction, so two timestamps that are the same instant can serialise differently — which matters when the text is a CouchDB document key, a database column, or part of an API response someone diffs. at.Timestamp always writes exactly three decimal places, so encoding is stable and lexical order matches chronological order.

This package started inside invopop/couch and was moved out so anything can use it without depending on a persistence layer.

Install

go get github.com/invopop/at

Usage

Timestamp embeds time.Time, so every method you already know is there:

ts := at.Now()
fmt.Println(ts.String())  // 2026-08-03T12:29:08.123Z
fmt.Println(ts.Year())    // 2026, via the embedded time.Time
fmt.Println(ts.Before(other.Time))

In a struct it marshals and unmarshals as a quoted string, and an empty value round-trips as null:

type Invoice struct {
	IssuedAt at.Timestamp  `json:"issued_at"`
	PaidAt   *at.Timestamp `json:"paid_at,omitempty"`
}
{ "issued_at": "2026-08-03T12:29:08.123Z" }

Parsing takes any RFC3339 timestamp — milliseconds optional, offset or Z — and normalises it to UTC, so input that was written by something less strict still reads:

ts, _ := at.ParseTimestamp("2026-08-03T12:29:08.123Z")
ts, _ = at.ParseTimestamp("2026-08-03T14:29:08.123+02:00") // → 12:29:08.123Z
ts, _ = at.ParseTimestamp("2026-08-03T12:29:08Z")          // → 12:29:08.000Z

Local times

LocalTime is the same idea for a wall-clock time that must keep its zone rather than being normalised to UTC — a scheduled hour in a merchant's own timezone, for example:

lt := at.LocalTimeNow(loc)
fmt.Println(lt.String())  // 2026-08-03T14:29:08.123+02:00

Notes

  • Marshalling always emits three decimal places, padding or truncating as needed. A timestamp with sub-millisecond precision loses it on the way out.
  • The zero Timestamp marshals as null, and null unmarshals back to the zero value, so IsZero() is the test for "not set".

License

Apache 2.0 — see LICENSE.

About

Simplified time library for dealing with timestamps that include millisecond precision, useful for databases.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages