Skip to content

time ​

Before You Start

  • Applies to: Go 1.21+ (examples verified with Go 1.22) · Prerequisites: Base: Data Types · Read time: about 10 min

The time package provides functions and methods related to time and calendar.

The time.Now() function can get the current time:

go
func Now() Time
go
now := time.Now()
fmt.Println(now)
//2022-11-17 10:00:18.6983438 +0800 CST m=+0.007095001

Its return data type is the Time struct, which contains many time operation methods.

go
func (t *Time) nsec() int32 // Nanoseconds

func (t *Time) sec() int64 // Seconds

func (t *Time) unixSec() // Returns seconds in Unix time format

func (t *Time) addSec(d int64) // Add seconds

func (t *Time) setLoc(loc *Location) // Set location

func (t *Time) stripMono() // Remove monotonic clock reading from time

func (t Time) After(u Time) // Check if a time is after another

func (t Time) Before(u Time) bool // Check if a time is before another

func (t Time) Equal(u Time) bool // Check if two times represent the same instant

func (t Time) Sub(u Time) Duration // Calculate the difference between two times

func (t Time) Add(d Duration) Time // Add a time duration

Time Units ​

The time package stores basic time unit constants:

go
const (
  minDuration Duration = -1 << 63
  maxDuration Duration = 1<<63 - 1
)

const (
  Nanosecond  Duration = 1
  Microsecond          = 1000 * Nanosecond
  Millisecond          = 1000 * Microsecond
  Second               = 1000 * Millisecond
  Minute               = 60 * Second
  Hour                 = 60 * Minute
)

Their type is time.Duration, with the smallest unit being nanoseconds and the largest being hours.

Formatting ​

Time types can be formatted for output. Note that in Go, the formatting template is not the common yyyy-mm-dd format, but uses Go's birth time as the template. Go was born on January 2, 2006, at 3:04 PM.

Example:

go
now := time.Now()

24-hour format output:

go
fmt.Println(now.Format("2006-01-02 15:04:05 Monday Jan"))
//2022-11-17 10:44:48 Thursday Nov

Output only the date:

go
fmt.Println(now.Format("2006-01-02"))
//2022-11-17

Output only 12-hour time format:

go
fmt.Println(now.Format("15:04:05 PM"))
//10:48:47 AM

Parsing Time ​

Often we have a requirement to convert a string time in a specific format to Go's time struct. This is what we're going to do next.

go
func main() {
   location, err := time.LoadLocation("Asia/Shanghai")
   if err != nil {
      fmt.Println(err)
      return
   }

   inLocation, err := time.ParseInLocation("2006/01/02", "2012/10/12", location)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(inLocation.String())
}

Final output:

2012-10-12 00:00:00 +0800 CST

Timer ​

Timer is a timer that exposes a channel. When the specified time arrives, the channel will receive a message and close.

go
func NewTimer(d Duration) *Timer

You can create a new timer through time.NewTimer():

go
func main() {
  timer := time.NewTimer(time.Second)
  defer timer.Stop()
  select {
  case t := <-timer.C:
    fmt.Println(t)
  }
}
2023-09-25 21:25:03.5696803 +0800 CST m=+1.007908001

After using the timer, it should be closed promptly.

Ticker ​

Ticker is a timer. The difference from Timer is that Timer is one-time, while Ticker triggers periodically.

go
func NewTicker(d Duration) *Ticker

You can create a new ticker through time.NewTicker():

go
func main() {
  ticker := time.NewTicker(time.Second)
  defer ticker.Stop()
  for i := 0; i < 3; i++ {
    select {
    case t := <-ticker.C:
      fmt.Println(t)
    }
  }
}
2023-09-25 21:29:20.4429256 +0800 CST m=+1.009508401
2023-09-25 21:29:21.4512075 +0800 CST m=+2.017790301
2023-09-25 21:29:22.4501592 +0800 CST m=+3.016742001

Similarly, after using the ticker, it should also be closed promptly.

Sleep ​

time.Sleep() can put the current goroutine in a suspended state for a certain period. During this time, the goroutine will be blocked until it resumes running.

go
func Sleep(d Duration)
go
func main() {
  start := time.Now()
  fmt.Println(start)
  time.Sleep(time.Second * 2)
  end := time.Now()
  fmt.Println(end)
}
2023-09-25 21:36:35.7229057 +0800 CST m=+0.001627901
2023-09-25 21:36:37.7347742 +0800 CST m=+2.013496401

The above program will block for two seconds after outputting start, then output end.

Complete Example ​

The program below runs as-is: copy it into a file and execute go run main.go, or paste it into the Go Playground.

go
package main

import (
	"fmt"
	"time"
)

func main() {
	t := time.Date(2026, 10, 15, 9, 30, 0, 0, time.UTC)
	fmt.Println(t.Format(time.RFC3339))

	parsed, err := time.Parse("2006-01-02", "2026-10-15")
	fmt.Println(parsed.Year(), parsed.Month(), err == nil)

	d := 90 * time.Minute
	fmt.Println(d, d.Hours())

	next := t.Add(24 * time.Hour)
	fmt.Println(next.After(t), next.Format("2006-01-02"))
}

Expected output:

text
2026-10-15T09:30:00Z
2026 October true
1h30m0s 1.5
true 2026-10-16

Common Pitfalls ​

  • Compare with Equal, not ==. time.Time carries a monotonic clock reading and location; Equal is the correct comparison.
  • Layouts use the reference time. 2006-01-02 15:04:05 is the layout string, not YYYY-MM-DD.
  • Parse returns UTC. Use ParseInLocation when the input is in a specific zone.
  • Stop tickers and timers. time.Ticker keeps firing until you call Stop.
  • Duration arithmetic can overflow. time.Duration is nanoseconds in an int64; multiply carefully.

Change Log ​

  • 2026-10-14: Added "Before You Start" notes, a complete runnable example with expected output, common pitfalls, and this change log.

Golang by www.golangdev.cn · Adapted in part from Golang 中文学习文档 (MIT, © 寒江蓑笠翁)