liveBook · Manning

Time API

As explained in 100 Go Mistakes and How to Avoid Them

The Go time API is the standard-library interface for obtaining, representing, and manipulating times and durations.

Calling time.Now() inside time-sensitive logic can make unit tests brittle: machine load may change which events a duration-based cache removes. Treat the clock as a dependency when deterministic tests matter. section 11.6

type Cache struct {
    mu     sync.RWMutex
    events []Event
}
 
type Event struct {
    Timestamp time.Time
    Data string
}
 
func (c *Cache) TrimOlderThan(since time.Duration) {
    c.mu.RLock()
    defer c.mu.RUnlock()
 
    t := time.Now().Add(-since)               #1
    for i := 0; i < len(c.events); i++ {
        if c.events[i].Timestamp.After(t) {
            c.events = c.events[i:]           #2
            return
        }
    }
}

The cache computes a cutoff with time.Now().Add(-since), then removes older events from its time-sorted slice. section 11.6

Replace the live clock in tests

Define a now func() time.Time field, initialize it with time.Now in NewCache, and override it with a fixed timestamp in tests. Events at 04, 05, and 06 seconds with a fixed current time of 06 seconds make a 15-millisecond trim deterministic. Alternatives include passing the current time to TrimOlderThan or storing time.Now in a replaceable package variable; choose the boundary that best fits the design. section 11.6 section 11.10

How 100 Go Mistakes and How to Avoid Them covers it

How deep it goes
Explains time.Now-driven flakiness and three clock-injection options, but does not survey the entire time API.
Examples
Uses a time-sorted event cache, time.Now timestamps, fixed timestamps, and TrimOlderThan test variants.
What it assumes
Assumes familiarity with Go methods, structs, time.Time, durations, and unit-test assertions.
What you can do after
Diagnose flaky time-based tests and apply clock injection or client-provided timestamps to make them deterministic.
How it connects
Connects the time API with unit testing, dependency injection, hidden dependencies, and synchronization.

This explainer was generated by Manning's knowledge graph from the text of 100 Go Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.