As programmers, we often need to process time. In Go, the standard library time provides corresponding capabilities.
This article will introduce some important functions and methods in the time library, hoping to help those children's shoes that need Baidu when they encounter Go time problems.
Coping with time zone issues
In programming, we often encounter eight-hour time difference. This is caused by time zone differences, and in order to better address them, we need to understand several time definition criteria.
GMT (Greenwich Mean Time), Greenwich is usually. GMT calculates time based on the rotation and revolving of the earth. It stipulates that the sun passes through the Royal Greenwich Observatory in the suburbs of London, England at 12 noon every day. GMT is the pre-world standard time.
UTC (Coordinated Universal Time), coordinates world time. UTC is more accurate than GMT, and it calculates time based on the atomic clock. Without the need for accuracy to seconds, it can be considered that UTC=GMT. UTC is the current world standard time.
Starting from the Greenwich Primordial Meridian, it is positive to the east and negative to the west. The world is divided into 24 standard time zones, with an hour apart from the adjacent time zones.
package main import ( "fmt" "time" ) func main() { (()) }
Mainland China uses the standard time of the East Eighth Time Zone, namely, Beijing time CST, China Standard Time.
$ go run 2022-07-17 16:37:31.186043 +0800 CST m=+0.000066647
This is the result under the default time zone. +0800 CST will be marked in the printing of ().
Suppose we are in the Los Angeles time zone in the United States, what are the results?
$ TZ="America/Los_Angeles" go run 2022-07-17 01:39:12.391505 -0700 PDT m=+0.000069514
It can be seen that the result at this time is -0700 PDT time, that is, PDT (Pacific Daylight Time) Pacific summer time. Due to time zone differences, the time results for the two executions differ by 15 hours.
Note that when using Docker containers, the default time zone of the system is UTC time (0 time zone), which is eight hours apart from the Beijing time we actually need. This is a classic scenario that leads to the eight-hour time difference problem.
For the response strategy for time zone problems, you can view the loading logic of the initLocal() function in src/time/zoneinfo_unix.go in detail. For example, it can be solved by specifying the environment variable TZ, modifying the /etc/localtime file, etc.
Because the time zone issue is very important, it is discussed in the first part of the article. The use of the time library will begin below.
Time instant
The most core object of the time library is the structure. It is defined as follows, to represent the time of a certain moment.
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 terms of time processing, computers mainly involve two types of clocks.
- Wall time, also known as clock time, is used to represent specific dates and times.
- Monotonic clocks always ensure that time is forward and there will be no callback problems with the wall clock, so it is very suitable for measuring duration periods.
The wall and ext fields are used to record wall clocks and monotonic clocks, with a precision of nanoseconds. The corresponding number of digits of the field is associated with the specific year, month, day, hour, minute, second and other information used to determine the time.
The loc field records the time zone location, and when loc is nil, it defaults to UTC time.
Because it is used to represent time instants with nanosecond accuracy, it should usually be stored and passed as a value in a program, rather than a pointer.
That is, in time variables or structure fields, we should use , not *.
Get
We can get the current local time through the Now function
func Now() Time {}
You can also obtain the specified time based on the time and time zone parameters such as year, month, day, etc.
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {}
Convert timestamp
In the computer world, UTC time is used January 1, 1970 at 0:00:00 as Unix time 0. The so-called time instant is converted into a Unix timestamp, which calculates the number of seconds, microseconds, etc. that passes from Unix time 0 to a specified instant.
func (t Time) Unix() int64 {} // Number of seconds elapsed from Unix time 0func (t Time) UnixMicro() int64 {} // Number of microseconds elapsed from Unix time 0func (t Time) UnixMilli() int64 {} // Number of milliseconds elapsed from Unix time 0func (t Time) UnixNano() int64 {} // from Unix time 0 The number of nanoseconds passed
Get basic fields
t := () (()) // 2022 July 17 (()) // 2022 (()) // July (()) // 2022 28 (()) // 22 21 56 (()) // 17 (()) // Sunday (()) // 22 (()) // 21 (()) // 56 (())// 494313000 (()) // 198
Duration
Duration is used to represent the time elapsed between two time moments. It represents nanosecond count by int64, and the limit it can represent is about 290 years.
// 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, duration is just a number in nanoseconds. If the duration is equal to 100000000, it represents a meaning of 1 second or 1000 milliseconds or 10000000 microseconds or 100000000000 nanoseconds.
For example, two time instant values separated by 1 hour, the duration between them is
1*60*60*1000*1000*1000
These duration constant values are defined in Go's time package
const ( Nanosecond Duration = 1 Microsecond = 1000 * Nanosecond Millisecond = 1000 * Microsecond Second = 1000 * Millisecond Minute = 60 * Second Hour = 60 * Minute )
At the same time, a method is provided to obtain the value of the granularity of each time
func (d Duration) Nanoseconds() int64 {} // Nanosecondsfunc (d Duration) Microseconds() int64 {} // Microsecondsfunc (d Duration) Milliseconds() int64 {} // millisecondsfunc (d Duration) Seconds() float64 {} // Secondfunc (d Duration) Minutes() float64 {} // minutefunc (d Duration) Hours() float64 {} // Hour
Time calculation
After learning the time moment and duration, let’s look at how to do time calculations.
func (t Time) Add(d Duration) Time {}
The Add function is used to increase/decrease the duration of (the positive value of d indicates increase and negative value indicates decrease). We can increase or decrease the time above the specified nanosecond level for a certain instantaneous time.
func (t Time) Sub(u Time) Duration {}
The Sub function can obtain the duration between two time instants.
func (t Time) AddDate(years int, months int, days int) Time {}
The AddDate function increases/decreases the value of the dimensions of year, month, and day.
Of course, calculation based on the current time instant () is the most common requirement. Therefore, the time package also provides the following convenient time calculation functions.
func Since(t Time) Duration {}
The Since function is a shortcut to ().Sub(t).
func Until(t Time) Duration {}
The Until function is a shortcut to (()).
Example of usage
t := () (t) // 2022-07-17 22:41:06.001567 +0800 CST m=+0.000057466 //Time increases by 1 hour (( * 1)) // 2022-07-17 23:41:06.001567 +0800 CST m=+3600.000057466 //Time increases by 15 minutes (( * 15))// 2022-07-17 22:56:06.001567 +0800 CST m=+900.000057466 //Time increases by 10 seconds (( * 10))// 2022-07-17 22:41:16.001567 +0800 CST m=+10.000057466 //Time decreases by 1 hour ((- * 1)) // 2022-07-17 21:41:06.001567 +0800 CST m=-3599.999942534 //Time decreases by 15 minutes ((- * 15))// 2022-07-17 22:26:06.001567 +0800 CST m=-899.999942534 //Time decreases by 10 seconds ((- * 10))// 2022-07-17 22:40:56.001567 +0800 CST m=-9.999942534 ( * 5) t2 := () // Calculate the duration from t to t2 ((t)) // 5.004318874s // 1 year later t3 := (1, 0, 0) // Calculate the duration from t to the current ((t)) // 5.004442316s // Calculate the duration from now to next year ((t3)) // 8759h59m59.999864s
Format time
In other languages, common time templates are generally used to format time. For example, Python uses %Y for year, %m for month, %d for day, etc.
However, Go is different. It uses a fixed time (it should be noted that using other times is not possible) as the layout template, and this fixed time is the birth time of the Go language.
Mon Jan 2 15:04:05 MST 2006
Format time involves two conversion functions
func Parse(layout, value string) (Time, error) {}
The Parse function is used to convert a time string into an object according to its corresponding layout.
func (t Time) Format(layout string) string {}
The Formate function is used to convert an object into a time string according to the given layout.
Example
const ( layoutISO = "2006-01-02" layoutUS = "January 2, 2006" ) date := "2012-08-09" t, _ := (layoutISO, date) (t) // 2012-08-09 00:00:00 +0000 UTC ((layoutUS)) // August 9, 2012
In the time library, Go provides some predefined layout template constants, which can be used directly.
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" )
Below is our optional layout parameter comparison table
Year 06/2006 moon 01/1/Jan/January day 02/2/_2 Week Mon/Monday Hour 03/3/15 point 04/4 Second 05/5 毫Second .000/.999 微Second .000000/.999999 纳Second .000000000/.999999999 am/pm PM/pm Time zone MST Time zoneHour数差-0700/-07/-07:00/Z0700/Z07:00
Time zone conversion
At the beginning of the article, we introduce the time zone issue. If in the code, we need to get the same result under different time zones, we can use its In method.
func (t Time) In(loc *Location) Time {}
It is very simple to use, just look at the sample code
now := () (now) // 2022-07-18 21:19:59.9636 +0800 CST m=+0.000069242 loc, _ := ("UTC") ((loc)) // 2022-07-18 13:19:59.9636 +0000 UTC loc, _ = ("Europe/Berlin") ((loc)) // 2022-07-18 15:19:59.9636 +0200 CEST loc, _ = ("America/New_York") ((loc)) // 2022-07-18 09:19:59.9636 -0400 EDT loc, _ = ("Asia/Dubai") ((loc)) // 2022-07-18 17:19:59.9636 +0400 +04
Summarize
Overall, the time processing functions and methods provided by the time library basically meet our usage needs.
Interestingly, Go time formatting conversion must use Go's birth time, which is indeed narcissistic enough.
This is the end of this article about detailed explanation of time processing in Go. For more relevant time processing content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!