snapshot of 8b9e9fcfc8b13c2d29024f6f756b28bc6851512b Annotations about the code that implements koment.

internal/store/timestamp.go

1 package store
2
3 import (
4 "fmt"
5 "time"
6
7 yaml "go.yaml.in/yaml/v3"
8 )
9
10 // Timestamp is an instant in UTC. A v1 record carried a calendar date; both
11 // forms are read and only the instant is written back, so a reader comparing
12 // two records never has to know which generation wrote them.
13 type Timestamp struct{ time.Time }
14
15 const (
16 timestampLayout = time.RFC3339
17 dateLayout = "2006-01-02"
18 )
19
20 func Now() Timestamp { return Timestamp{time.Now().UTC().Truncate(time.Second)} }
21
22 func ParseTimestamp(text string) (Timestamp, error) {
23 if instant, err := time.Parse(timestampLayout, text); err == nil {
24 return Timestamp{instant.UTC()}, nil
25 }
26 if day, err := time.Parse(dateLayout, text); err == nil {
27 return Timestamp{day.UTC()}, nil
28 }
29 return Timestamp{}, fmt.Errorf("%q is neither an RFC3339 instant nor a %s date", text, dateLayout)
30 }
31
32 func (t Timestamp) MarshalYAML() (any, error) { return t.UTC().Format(timestampLayout), nil }
33
34 // UnmarshalYAML reads the node rather than a decoded value because an
35 // unquoted 2026-08-05 resolves to !!timestamp, which will not decode into a
36 // string at all. Reading Value sidesteps tag resolution entirely.
37 func (t *Timestamp) UnmarshalYAML(node *yaml.Node) error {
38 if node.Kind != yaml.ScalarNode {
39 return fmt.Errorf("a timestamp is a single value, got %s", node.Tag)
40 }
41 parsed, err := ParseTimestamp(node.Value)
42 if err != nil {
43 return err
44 }
45 *t = parsed
46 return nil
47 }

Find an annotation

Search file paths, rationale, kinds, and authors.

moveEnter openEsc close