> ## Content Index
> Fetch the complete content index at: https://huizhou92.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Learn How to Handle Time In Golang
- URL: https://huizhou92.com/learn-how-to-handle-time-in-go/
- Published: 2024-04-22T11:15:03.000Z
- Updated: 2024-04-22T11:15:03.000Z
- Description: Learn How to Handle Time In Golang. Note: Non-members can read the full story in this link . Handling time is a common task for programmers. In Go, the sta。
- Author: huizhou92
- Tags: #Migrated-1788833207488, #Import 2026-09-08 02:07

Note: Non-members can read the full story in this [link](https://hxzhouh.com/2024/04/19/Learn%20How%20to%20Handle%20Time%20In%20Golang/?ref=huizhou92.com).

Handling time is a common task for programmers. In Go, the standard library `time` provides the necessary capabilities.

This article will introduce some important functions and methods in the `time` package, hoping to help those who often need to deal with time-related issues in Go.

### Handle Time Zones

In programming, we often encounter the issue of an **eight-hour time difference**. This is caused by differences in time zones. To better handle them, we need to understand several time definition standards.

GMT (Greenwich Mean Time) is based on the Earth's rotation and revolution to calculate time. It defines noon as the time when the sun passes through the Royal Greenwich Observatory in the suburbs of London, UK. GMT was the former World Standard Time.

UTC (Coordinated Universal Time) is more precise than GMT, calculated based on atomic clocks. In situations where precision to the second is not required, UTC can be considered equivalent to GMT. UTC is the current world standard time.

From the Prime Meridian at Greenwich, going east is positive, going west is negative. The globe is divided into 24 standard time zones, with neighboring time zones differing by one hour.

```go
package main 
 ​ 
 import ( 
     "fmt" 
     "time" 
 ) 
 ​ 
 func main() { 
     fmt.Println(time.Now()) 
 }
```

The standard time used in mainland China is in the GMT+8 time zone, known as China Standard Time (CST).

```go
$ go run main.go 
 2022-07-17 16:37:31.186043 +0800 CST m=+0.000066647
```

This is the result under the default time zone, and `+0800 CST` is indicated in the `time.Now()` printout.

Suppose we are in the Los Angeles time zone in the United States, what result do we get?

```go
$ TZ="America/Los_Angeles" go run main.go 
 2022-07-17 01:39:12.391505 -0700 PDT m=+0.000069514
```

As seen, the result at this time is `-0700 PDT`, which is Pacific Daylight Time. Due to the time zone difference, the results of the two executions differ by 15 hours.

Note that when using Docker containers, the system's default time zone is UTC (0-time zone), which is eight hours behind Beijing time as we need, leading to the classic scenario of the **eight-hour time difference** problem.

Strategies for dealing with time zone issues can be found in detail in the loading logic of the `initLocal()` function in `src/time/zoneinfo_unix.go`. For example, you can solve it by specifying the environment variable `TZ` or modifying the `/etc/localtime` file.

Because time zone issues are very important, they are discussed in the first part of the article. Let's now move on to the usage of the `time` package.

### Time Instant `time.Time`

The core object in the `time` package is the `time.Time` struct. Its definition, used to represent a specific moment in time, is as follows:

```go
type Time struct { 
     // wall and ext encode the wall time seconds, 
     // wall time nanoseconds, and optional monotonic 
     // clock reading in nanoseconds. 
     wall uint64 
     ext  int64 
     loc  *Location 
 }
```

In computer time handling, two types of clocks are mainly involved:

- A wall clock, also known as clock time, is used to represent specific dates and times.
- Monotonic clocks, always guarantee that time moves forward without the issue of wall clock rollback, making them suitable for measuring durations.

The `wall` and `ext` fields are used to record wall clock and monotonic clock times, with nanosecond precision. The bits of these fields are associated with specific information such as years, months, days, hours, minutes, and seconds.

The `loc` field records the time zone location. When `loc` is `nil`, it defaults to UTC.

Because `time.Time` is used to represent time instants with nanosecond precision, it is typically stored and passed as a value in programs, rather than a pointer.

That is, in time variables or struct fields, we should use `time.Time` rather than `*time.Time`.

Getting `time.Time`

We can get the current local time using the `Now` function:

```csharp
func Now() Time {}
```

Or, using the `Date` function, we can get a specified time based on the year, month, day, and other parameters, along with the time zone:

```go
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {}
```

Converting Timestamps

In the computer world, UTC 0 on January 1, 1970, is considered Unix time 0\. To convert a time instant into a Unix timestamp, we calculate the number of seconds, microseconds, etc., elapsed from Unix time 0 to the specified instant.

```go
func (t Time) Unix() int64       // Seconds since Unix time 0 
 func (t Time) UnixMicro() int64  // Microseconds since Unix time 0 
 func (t Time) UnixMilli() int64  // Milliseconds since Unix time 0 
 func (t Time) UnixNano() int64   // Nanoseconds since Unix time 0
```

Getting Basic Fields

```go
t := time.Now() 
 fmt.Println(t.Date())        // 2022 July 17 
 fmt.Println(t.Year())        // 2022 
 fmt.Println(t.Month())       // July 
 fmt.Println(t.ISOWeek())     // 2022 28 
 fmt.Println(t.Clock())       // 22 21 56 
 fmt.Println(t.Day())         // 17 
 fmt.Println(t.Weekday())     // Sunday 
 fmt.Println(t.Hour())        // 22 
 fmt.Println(t.Minute())      // 21 
 fmt.Println(t.Second())      // 56 
 fmt.Println(t.Nanosecond())  // 494313000 
 fmt.Println(t.YearDay())     // 198
```

### Duration `time.Duration`

`time.Duration` represents the time elapsed between two `time.Time` instants. It uses a `int64` to represent the count of nanoseconds, allowing for approximately 290 years of representation.

```go
// A Duration represents the elapsed time between two instants 
 // as an int64 nanosecond count. The representation limits the 
 // largest representable duration to approximately 290 years. 
 type Duration int64
```

In Go, `time.Duration` is simply a number in nanoseconds. If a duration is equal to 1000000000, it represents 1 second, or 1000 milliseconds, or 1000000 microseconds, or 1000000000 nanoseconds.

For example, the duration between two-time instants separated by 1 hour can be calculated as:

```markdown
1*60*60*1000*1000*1000
```

The `time` package defines constant values for these durations:

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

Additionally, `time.Duration` provides methods to get values at various time granularities:

```go
func (d Duration) Nanoseconds() int64   // Nanoseconds 
 func (d Duration) Microseconds() int64  // Microseconds 
 func (d Duration) Milliseconds() int64  // Milliseconds 
 func (d Duration) Seconds() float64     // Seconds 
 func (d Duration) Minutes() float64     // Minutes 
 func (d Duration) Hours() float64       // Hours
```

### Time Calculation

After learning about time instants and durations, let's see how to perform time calculations.

```go
func (t Time) Add(d Duration) Time {}
```

`Add` adds or subtracts (positive `d` means addition, negative `d` means subtraction) a `time.Duration` to a `time.Time`. We can add or subtract durations of specific nanosecond levels to a specific instant in time.

```go
func (t Time) Sub(u Time) Duration {}
```

`Sub` returns the duration between two-time instants.

```go
func (t Time) AddDate(years int, months int, days int) Time {}
```

`AddDate` adds or subtracts values based on the year, month, and day dimensions to a `time.Time`.

Of course, calculating based on the current time instant `time.Now()` is the most common requirement. Therefore, the `time` package also provides the following convenient time calculation functions:

```go
func Since(t Time) Duration {}
```

`Since` is a shortcut for `time.Now().Sub(t)`.

```go
func Until(t Time) Duration {}
```

`Until` is a shortcut for `t.Sub(time.Now())`.

Usage Example

```go
t := time.Now() 
fmt.Println(t)                              // 2022-07-17 22:41:06.001567 +0800 CST m=+0.000057466 
 
// Adding 1 hour to the time 
fmt.Println(t.Add(time.Hour * 1))           // 2022-07-17 23:41:06.001567 +0800 CST m=+3600.000057466 
// Adding 15 minutes 
fmt.Println(t.Add(time.Minute * 15))        // 2022-07-17 22:56:06.001567 +0800 CST m=+900.000057466 
// Adding 10 seconds 
fmt.Println(t.Add(time.Second * 10))        // 2022-07-17 22:41:16.001567 +0800 CST m=+10.000057466 
 
// Subtracting 1 hour 
fmt.Println(t.Add(-time.Hour * 1))          // 2022-07-17 21:41:06.001567 +0800 CST m=-3599.999942534 
// Subtracting 15 minutes 
fmt.Println(t.Add(-time.Minute * 15))       // 2022-07-17 22:26:06.001567 +0800 CST m=-899.999942534 
// Subtracting 10 seconds 
fmt.Println(t.Add(-time.Second * 10))       // 2022-07-17 22:40:56.001567 +0800 CST m=-9.999942534 
 
time.Sleep(time.Second * 5) 
t2 := time.Now() 
// Calculating the duration from t to t2 
fmt.Println(t2.Sub(t))                      // 5.004318874s 
// Time after 1 year 
t3 := t2.AddDate(1, 0, 0) 
// Calculating the duration from t to the current time 
fmt.Println(time.Since(t))                   // 5.004442316s 
// Calculating the duration from now to next year 
fmt.Println(time.Until(t3))                  // 8759h59m59.999864s
```

### Formatting Time

A universal time template is typically used to format time in other languages. For example, in Python, `%Y` represents year, `%m` represents month, `%d` represents a day, and so on.

However, Go is different. It uses a **fixed time** (it's important to note that using other times is not allowed) as the layout template, and this fixed time is the birth time of the Go language.

```shell
Mon Jan 2 15:04:05 MST 2006
```

Formatting time involves two conversion functions:

```go
func Parse(layout, value string) (Time, error) {}
```

`Parse` converts a time string to a `time.Time` object based on the layout it can correspond to.

```go
func (t Time) Format(layout string) string {}
```

`Format` converts a `time.Time` object to a time string based on the given layout.

Example

```go
const ( 
    layoutISO = "2006-01-02" 
    layoutUS  = "January 2, 2006" 
) 
date := "2012-08-09" 
t, _ := time.Parse(layoutISO, date) 
fmt.Println(t)                              // 2012-08-09 00:00:00 +0000 UTC 
fmt.Println(t.Format(layoutUS))             // August 9, 2012
```

In the `time` package, Go provides some predefined layout template constants that can be directly used.

```go
const ( 
    Layout      = "01/02 03:04:05PM '06 -0700"  // The reference time, in numerical order. 
    ANSIC       = "Mon Jan _2 15:04:05 2006" 
    UnixDate    = "Mon Jan _2 15:04:05 MST 2006" 
    RubyDate    = "Mon Jan 02 15:04:05 -0700 2006" 
    RFC822      = "02 Jan 06 15:04 MST" 
    RFC822Z     = "02 Jan 06 15:04 -0700"       // RFC822 with numeric zone 
    RFC850      = "Monday, 02-Jan-06 15:04:05 MST" 
    RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST" 
    RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone 
    RFC3339     = "2006-01-02T15:04:05Z07:00" 
    RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00" 
    Kitchen     = "3:04PM" 
    // Handy time stamps. 
    Stamp       = "Jan _2 15:04:05" 
    StampMilli  = "Jan _2 15:04:05.000" 
    StampMicro  = "Jan _2 15:04:05.000000" 
    StampNano   
 
 = "Jan _2 15:04:05.000000000" 
)
```

Here's a table of optional layout parameters:

```go
Year            06/2006 
Month           01/1/Jan/January 
Day             02/2/_2 
Weekday         Mon/Monday 
Hour            03/3/15 
Minute          04/4 
Second          05/5 
Milliseconds    .000/.999 
Microseconds    .000000/.999999 
Nanoseconds     .000000000/.999999999 
am/pm           PM/pm 
Timezone        MST 
Timezone offset -0700/-07/-07:00/Z0700/Z07:00
```

### Timezone Conversion

At the beginning of the article, we discussed timezone issues. If in your code, you need to get the result of the same `time.Time` in different time zones, you can use its `In` method.

```scss
func (t Time) In(loc *Location) Time {}
```

It's straightforward to use. Let's see an example code:

```css
now := time.Now() 
fmt.Println(now)                               // 2022-07-18 21:19:59.9636 +0800 CST m=+0.000069242 
 
loc, _ := time.LoadLocation("UTC") 
fmt.Println(now.In(loc))                        // 2022-07-18 13:19:59.9636 +0000 UTC 
 
loc, _ = time.LoadLocation("Europe/Berlin") 
fmt.Println(now.In(loc))                        // 2022-07-18 15:19:59.9636 +0200 CEST 
 
loc, _ = time.LoadLocation("America/New_York") 
fmt.Println(now.In(loc))                        // 2022-07-18 09:19:59.9636 -0400 EDT 
 
loc, _ = time.LoadLocation("Asia/Dubai") 
fmt.Println(now.In(loc))                        // 2022-07-18 17:19:59.9636 +0400 +04
```

### Conclusion

In general, the functions and methods provided by the `time` package for time processing to meet our usage needs.

Interestingly, Go's time formatting conversion must adopt Go's birth time. It's quite self-centered.

[文章索引](/article-index/)