Time and Duration
Time instant and the elapsed time between two instants
The Go standard library’s time package provides functionality for measuring and displaying time. It defines two core types that we’ll take a quick look at: Time and Duration.
Time represents an instant in time, while Duration represents the elapsed time between two instants.
Time
To get a variable of type time.Time, we can ask the computer for the current time, or we can construct a specific time ourselves:
now := time.Now()
then := time.Date(1989, 11, 29, 0, 0, 0, 0, time.UTC)We can also parse a string into a time value:
t, err := time.Parse(time.DateTime, "2006-01-02 15:04:05")We used one of the predefined layout constants above (time.DateTime) but we can also supply custom layouts. Layouts must use the reference time 01/02 03:04:05PM ‘06 -0700 to describe the desired pattern. This is one of Go’s peculiarities: instead of using placeholders like YYYY or MM, you use the values from the reference time in the format you expect. For example, here we use only the year and the month value:
t, err := time.Parse("2006-01", "1989-11")The reference time is supposed to be easy to remember because each value equals the position in a sequence:
01/02 03:04:05PM '06 -0700
Month: 1 (January)
Day: 2
Hour: 3 (3PM)
Minute: 4
Second: 5
Year: 6 (2006)
Timezone: 7 (MST is UTC -7 hours)
When turning a time to a string (e.g. for printing) we can use the default representation or again use a predefined or custom format layout:
fmt.Println(t) // default representation
fmt.Println(t.Format(time.DateOnly))
fmt.Println(t.Format("2006-01-02_15:04"))There are also methods for accessing various components of the time value. Here’s an exmple how to use them:
fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
t.Year(), t.Month(), t.Day(),
t.Hour(), t.Minute(), t.Second())And we compare two times like this:
then.Before(now) // true
then.After(now) // false
then.Equal(now) // falseDuration
To get the duration between two times:
diff := now.Sub(then)
fmt.Println(diff.Hours())You can advance a time by a given duration or move it backwards with a -:
now.Add(10 * time.Second) // future
now.Add(-24 * time.Hour) // pastPractical example
The time package hides many more subtle details around time zones, monotonic clocks and formatting but the basics above should be enough to get started. Here’s a practical example that provides gharchive.org style of file timestamps:
// TimestampsBetween returns timestamps for each hour between two times. // t2 is not included.
func TimestampsBetween(t1, t2 time.Time) []Timestamp {
start := t1.Truncate(time.Hour)
end := t2.Truncate(time.Hour)
var timestamps []Timestamp
for t := start; t.Before(end); t = t.Add(time.Hour) {
timestamps = append(timestamps, Timestamp{Time: t})
}
return timestamps
}You can find the full code here: https://github.com/go-monk/gharchive.

