The Go language is often programmed by combining simple functions, and error checking occurs for each function, so the code in general tends to be long.
Even when I want to do something small, I need to write code accordingly, but it is tedious to write from scratch every time, so I would like to write down the processes I often do for my own copy and paste.
Here is a note for myself on how to use the time
package to handle time in the Go language.
Location
Introduction.
Although the time is often handled in "JST", nowadays, the execution environment is not only the local PC, but also the server, Docker, Lambda, etc. Various locations can be assumed. However, nowadays, the execution environment is not only the local PC, but also the server, Docker, Lambda, etc. In some cases, the local time of the execution location may not be JST, so we first describe how to specify the location explicitly.
Time
The time is stored in the Time
structure. The Time
structure contains location information.
The two predefined locations in time
are "UTC (time.UTC
)" and "local (time.Local
)".
To use other locations such as "JST", you need to read the time zone registered in the execution environment in time.LoadLocation()
or create your own time zone in time.FixedZone()
,
To use other locations such as "JST", you need to read the time zone registered in the execution environment with time.LoadLocation()
or create your own time zone with time.FixedZone()
.
Use Time.In()
to generate Time
for one location and Time
for another.
t := time.Now().UTC() // Get current time in UTC fmt.Println(t) // 2020-05-12 20:14:31.2928348 +0000 UTC // Read JST from time zone tokyo, err := time.LoadLocation("Asia/Tokyo") if err != nil { return err } timeTokyo := t.In(tokyo) fmt.Println(timeTokyo) // 2020-05-13 05:14:31.2928348 +0900 JST // Create your own JST (name optional) jst := time.FixedZone("JST", +9*60*60) timeJst := t.In(jst) fmt.Println(timeJst) // 2020-05-13 05:14:31.2928348 +0900 JST
When getting the current time or creating a time, you might want to be aware of which location you are creating it in.
It may be possible to prepare a function to get the default location, following the time.Local
configuration.
var jstLocation *time.Location var jstOnce sync.Once func jst() *time.Location { if jstLocation == nil { jstOnce.Do(func() { l, err := time.LoadLocation("Asia/Tokyo") if err != nil { l = time.FixedZone("JST2", +9*60*60) } jstLocation = l }) } return jstLocation } func test() { t := time.Now().In(jst()) fmt.Println(t) }
Generate and retrieve time
Obtaining the current time
The current time can be obtained from time.Now()
. The location is time.Local
.
Generated by specifying a value
It is generated by specifying values ranging from years to nanoseconds.
Each value can be obtained using the Time
method.
The month is an int value starting with 1, but the String()
method is defined to allow output in English notation.
The week is an int value with Sunday starting at 0, but the String()
method is defined to allow output in English notation.
The "date" can also be retrieved together using Time.Date()
.
t := time.Date(2020, 1, 2, 3, 4, 5, 123456789, time.Local) fmt.Println(t) //2020-01-02 03:04:05.123456789 +0900 JST fmt.Println(t.Year()) // 2020 fmt.Println(t.Month()) // January fmt.Printf("%d\n", t.Month()) // 1 fmt.Println(t.Day()) // 2 fmt.Println(t.Weekday()) // Thursday fmt.Printf("%d\n", t.Weekday()) // 4 fmt.Println(t.Hour()) // 3 fmt.Println(t.Minute()) // 4 fmt.Println(t.Second()) // 5 fmt.Println(t.Nanosecond()) // 123456789 year, month, day := t.Date() fmt.Println(year) // 2020 fmt.Println(month) // January fmt.Println(day) // 3
character string format
Time can be generated from a string. It can also output time to a string in a specified format.
The format is not the common YYYY-MM-DD HH:mm:ss
format, but is quite special, so I will first explain the format.
Format designation method
01/02 03:04:05PM '06 -0700
The format is specified by how the time "∗" is displayed in the format.
For example, the case of YYYY/MM/DD HH:mm:ss
is as follows
t := time.Date(2020, 1, 2, 3, 4, 5, 123456789, time.Local) fmt.Println(t) // 2020-01-02 03:04:05.123456789 +0900 JST fmt.Println(t.Format("2006/01/02 15:04:05")) // 2020/01/02 03:04:05
Format Notes
- When zero-filling, place a zero in front of it.
- When displaying nanoseconds, the decimal point is filled with zeros.
- Since the original time is 3 p.m.,
hour
is "3" in 12h and "15" in 24h. - The 24h display of
hour
is 2-digit with 15, so it is not possible to use a one-digit display with no zeros filled in. - The time zone is "-7" "MST" and
MST
is used to indicate the time zone - English notation can be used in the morning and afternoon, and
PM
should be listed. - The month can be written in English, so for 2020/1/2, enter
January
orJan
since it is January. - The day of the week in English can be used, e.g.,
Monday
orMon
for Monday, 1/2/2020.
t := time.Date(2020, 1, 2, 3, 4, 5, 123456789, time.Local) fmt.Println(t) // 2020-01-02 03:04:05.123456789 +0900 JST // 2020/1/2(Thu) 03:04:05(.123)AM JST +09:00 fmt.Println(t.Format("2006/1/2(Mon) 03:04:05(.000)PM MST -07:00"))
The reason why this particular date is the base of the format is because the base date is 01/02 03:04:05PM '06 -0700
,
The time is sequentially numbered 1, 2, 3... The reason why such a special date is used as the basis of the format is that the time is numbered 1, 2, 3... in English.
However, since it is not something that comes up quickly, I would make a note of the following format and use it while looking at the notes.
2006-01-02 [12h]03:04:05PM [24h]15:04:05 -07:00 MST January Monday
Generate time from string
Generating time from a string is done by time.ParseInLocation()
.
The format in which the time is described is specified in the aforementioned manner.
If no location information is given in the string, the location of the second argument is applied.
t, err := time.ParseInLocation("2006-01-02", "2020-12-31", time.Local) if err != nil { return err } fmt.Println(t) // 2020-12-31 00:00:00 +0900 JST
If the string contains location information, it will be applied at that location if it is the same as the location specified in the second argument, Otherwise, it will not be set.
In other words, setting a string to a location other than UTC or local will not be well identified.
unit of time
When performing time operations, we are dealing with lengths of time, the smallest unit being the nanosecond, which is an integer value.
However, since integers have too many digits to be understood if they are handled as they are, they are assigned a different type name, Duration
, and the length of time is handled via Duration
.
The Duration
contains the Hour・Minute・Second・Millisecond...
constants, which are used to write Duration
to improve the readability of the time length.
For example, to calculate the time that adds "2 hours and 3 minutes" to the current time, the following is used.
t := time.Now().Add(time.Hour * 2 + time.Minute * 3)
calculation
addition and subtraction
The Time.Add()
can be used to add or subtract time. The unit of time length is Duration
as described above.
t := time.Date(2020, 1, 2, 3, 4, 5, 123456789, time.Local) tAdd := t.Add(time.Hour) // 2020-01-02 04:04:05.123456789 +0900 JST tSub := t.Add(-time.Hour) // 2020-01-02 02:04:05.123456789 +0900 JST
Differential (diff)
You can use Time.Sub()
to find the time difference between two times. The unit of length of time is Duration
.
The sequence is "a - b" if "a.Sub(b)" is the same as the formula.
a := time.Date(2020, 1, 2, 3, 4, 5, 123456789, time.Local) b := a.Add(-time.Hour) fmt.Println(a.Sub(b)) // 1h0m0s
Adding and Subtracting Dates
Since it is troublesome to calculate Duration
for dates such as "1 year later" or "3 days earlier," a dedicated method (Time.AddDate()
) is provided for date addition and subtraction.
Specify the number of date additions and subtractions in the order of "year, month, day, and year" in the argument.
t := time.Date(2020, 1, 2, 3, 4, 5, 123456789, time.Local) tt := t.AddDate(1, 0, -3) // 1 year 3 days ago fmt.Println(t) // 2020-01-02 03:04:05.123456789 +0900 JST fmt.Println(tt) // 2020-12-30 03:04:05.123456789 +0900 JST
Values below the time after the calculation are carried over as they are.
Unfortunately, no method is provided for determining date differences.
Comparison
Time
has several methods for comparing times.
If you use Time.Sub()
to find and check the absolute difference between two times, you only need to remember one method.
Since Time
is a structure, the ==
operator can be used, but since it also compares locations, it should not be used as a method to check if they are the same time.
diff := a.Sub(b) if diff == 0 { fmt.Println("同じ") } else if diff > 0 { fmt.Println("aが後") } else { fmt.Println("aが前") }
Date Comparison
To compare two time dates in Time.Sub()
, the hour and day must be set to zero before the date is compared.
Since there is no means provided to do these things in a benign manner, we will simply generate a new time from the time we wish to compare, with the hour and the day set to zero, and then compare them.
aZero := time.Date(a.Year(), a.Month(), a.Day(), 0, 0, 0, 0, time.Local) bZero := time.Date(b.Year(), b.Month(), b.Day(), 0, 0, 0, 0, time.Local) diff := aZero.Sub(bZero) if diff == 0 { fmt.Println("同じ") } else if diff > 0 { fmt.Println("aが後") } else { fmt.Println("aが前") }
Sleep
The "Sleep" function, which waits for the specified Duraion
, is also defined in time
.
time.Sleep(time.Duration.Second * 3)
Reference Articles
Impressions, etc.
The format designation doesn't look like a format at first glance..." I would have preferred something like YYYY-MM-DD HH:mm:ss
....