Tìm hiểu thời gian và ngày trong Golang
Post on: 2023-04-17 23:33:59 | in: Golang
Trong Go, gói time được sử dụng để làm việc với các giá trị thời gian và ngày.
- Sử dụng Gói Context trong GO
- Triển khai máy chủ HTTP cơ bản bằng cách sử dụng Go
- Xây dựng một ứng dụng chat sử dụng gRPC và React phần 2
Tổng quan
Thời gian hoặc ngày tháng được đại diện trong Go bằng cấu trúc time.Time
. Thời gian cũng có thể được biểu diễn dưới dạng
- Unix Time (Also known as Epoch Time) – Đó là số giây trôi qua kể từ 00:00:00 UTC ngày 1 tháng 1 năm 1970. Thời điểm này cũng được gọi là epoch của Unix.
Structure
Đối tượng time.Time được sử dụng để đại diện cho một thời điểm cụ thể. Cấu trúc time.Time được định nghĩa như sau:
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
//Location to represent timeZone
// The nil location means UTC
loc *Location
}
Như bạn có thể thấy, mỗi đối tượng time.Time đều có một giá trị location liên kết được sử dụng để xác định phút, giờ, tháng, ngày và năm tương ứng với thời gian đó.
Tạo một thời gian mới
Sử dụng time.Now()Hàm này có thể được sử dụng để lấy thời điểm địa phương hiện tại. Chữ ký của hàm là:
func Now() Time
Sử dụng time.Date()
Hàm này trả về thời gian có định dạng yyyy-mm-dd hh:mm:ss + nsec nano giây với múi giờ phù hợp với vị trí được chỉ định. Chữ ký của hàm là:
func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
Hiểu về Duration
duration là thời gian đã trôi qua giữa hai thời điểm. Nó được biểu diễn dưới dạng int64nanosecond. Vì vậy, trong Go, duration không phải là gì khác ngoài một con số biểu thị thời gian tính bằng nanosecond. Vì vậy, nếu giá trị của duration là 1000000000, thì nó đại diện cho 1 giây hoặc 1000 mili giây hoặc 10000000000 nanosecond.
Ví dụ, thời lượng giữa hai giá trị thời gian cách nhau 1 giờ sẽ là giá trị dưới đây, tương đương với số nanosecond trong 1 giờ.
1 *60*60*1000*1000*1000
Nó được biểu diễn như sau trong gói time.
type Duration int64
Dưới đây là một số duration thông dụng được định nghĩa trong gói "time":
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
Minute = 60 * Second
Hour = 60 * Minute
)
Hàm được định nghĩa trên đối tượng time.Time
trả về Duration
bao gồm:
- func (t Time) Sub(u Time) Duration – Trả về thời gian trễ giữa hai thời điểm t-u.
- func Since(t Time) Duration – Trả về khoảng thời gian đã trôi qua kể từ thời điểm t.
- func Until(t Time) Duration – Trả về khoảng thời gian còn lại cho đến thời điểm t.
Thêm hoặc trừ thời gian
Bây giờ khi bạn đã hiểu được về duration
, hãy xem cách chúng ta có thể thêm hoặc trừ một khoảng thời gian từ một thời điểm cụ thể.
Golang's time
package định nghĩa hai cách để thêm hoặc trừ một khoảng thời gian từ một thời điểm:
- Hàm
Add
- được sử dụng để thêm/trừ mộtduration
vào thời điểmt
. Vìduration
có thể được biểu diễn dưới dạng giờ, phút, giây, mili giây, micro giây và nano giây, do đó hàmAdd
có thể được sử dụng để thêm/trừ các giá trị này từ một thời điểm. Chữ ký của nó là:
func (t Time) Add(d Duration) Time
- Hàm AddDate - nó được sử dụng để thêm / bớt số năm, tháng và ngày vào thời gian t. Chữ ký của nó là:
func (t Time) AddDate(years int, months int, days int) Time
Ghi chú: Giá trị dương được sử dụng để thêm vào thời gian và giá trị âm được sử dụng để trừ. Hãy xem một ví dụ về cách thêm và trừ thời gian.
Thêm thời gianDưới đây là đoạn mã để thêm vào thời gian:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
//Add 1 hours
newT := t.Add(time.Hour * 1)
fmt.Printf("Adding 1 hour\n: %s\n", newT)
//Add 15 min
newT = t.Add(time.Minute * 15)
fmt.Printf("Adding 15 minute\n: %s\n", newT)
//Add 10 sec
newT = t.Add(time.Second * 10)
fmt.Printf("Adding 10 sec\n: %s\n", newT)
//Add 100 millisecond
newT = t.Add(time.Millisecond * 10)
fmt.Printf("Adding 100 millisecond\n: %s\n", newT)
//Add 1000 microsecond
newT = t.Add(time.Millisecond * 10)
fmt.Printf("Adding 1000 microsecond\n: %s\n", newT)
//Add 10000 nanosecond
newT = t.Add(time.Nanosecond * 10000)
fmt.Printf("Adding 1000 nanosecond\n: %s\n", newT)
//Add 1 year 2 month 4 day
newT = t.AddDate(1, 2, 4)
fmt.Printf("Adding 1 year 2 month 4 day\n: %s\n", newT)
}
Output:
Adding 1 hour:
2020-02-01 02:16:35.893847 +0530 IST m=+3600.000239893
Adding 15 minute:
2020-02-01 01:31:35.893847 +0530 IST m=+900.000239893
Adding 10 sec:
2020-02-01 01:16:45.893847 +0530 IST m=+10.000239893
Adding 100 millisecond:
2020-02-01 01:16:35.903847 +0530 IST m=+0.010239893
Adding 1000 microsecond:
2020-02-01 01:16:35.903847 +0530 IST m=+0.010239893
Adding 1000 nanosecond:
2020-02-01 01:16:35.893857 +0530 IST m=+0.000249893
Adding 1 year 2 month 4 day:
2021-04-05 01:16:35.893847 +0530 IST
Trừ thời gian
Dưới đây là đoạn mã để trừ thời gian:
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
//Add 1 hours
newT := t.Add(-time.Hour * 1)
fmt.Printf("Subtracting 1 hour:\n %s\n", newT)
//Add 15 min
newT = t.Add(-time.Minute * 15)
fmt.Printf("Subtracting 15 minute:\n %s\n", newT)
//Add 10 sec
newT = t.Add(-time.Second * 10)
fmt.Printf("Subtracting 10 sec:\n %s\n", newT)
//Add 100 millisecond
newT = t.Add(-time.Millisecond * 10)
fmt.Printf("Subtracting 100 millisecond:\n %s\n", newT)
//Add 1000 microsecond
newT = t.Add(-time.Millisecond * 10)
fmt.Printf("Subtracting 1000 microsecond:\n %s\n", newT)
//Add 10000 nanosecond
newT = t.Add(-time.Nanosecond * 10000)
fmt.Printf("Subtracting 1000 nanosecond:\n %s\n", newT)
//Add 1 year 2 month 4 day
newT = t.AddDate(-1, -2, -4)
fmt.Printf("Subtracting 1 year 2 month 4 day:\n %s\n", newT)
}
Output:
Subtracting 1 hour:
2020-02-01 00:18:29.772673 +0530 IST m=-3599.999784391
Subtracting 15 minute:
2020-02-01 01:03:29.772673 +0530 IST m=-899.999784391
Subtracting 10 sec:
2020-02-01 01:18:19.772673 +0530 IST m=-9.999784391
Subtracting 100 millisecond:
2020-02-01 01:18:29.762673 +0530 IST m=-0.009784391
Subtracting 1000 microsecond:
2020-02-01 01:18:29.762673 +0530 IST m=-0.009784391
Subtracting 1000 nanosecond:
2020-02-01 01:18:29.772663 +0530 IST m=+0.000205609
Subtracting 1 year 2 month 4 day:
2018-11-27 01:18:29.772673 +0530 IST
Định dạng/ phân tích thời gian
Nếu bạn đã làm việc với định dạng/ phân tích ngày giờ trong các ngôn ngữ khác, bạn có thể đã nhận thấy rằng các ngôn ngữ khác sử dụng các ký tự đặc biệt để định dạng thời gian/ngày. Ví dụ như trong Ruby, ngôn ngữ này sử dụng
%d cho ngày %Y cho năm v.v.
Go, thay vì sử dụng các ký tự như trên, sử dụng các giá trị định dạng thời gian và ngày trông giống như ngày tháng và thời gian thực tế. Go sử dụng định dạng thời gian chuẩn, bao gồm:
Mon Jan 2 15:04:05 MST 2006 (MST is GMT-0700)
or
01/02 03:04:05PM '06 -0700
Vì vậy, nếu bạn nhận thấy, Go sử dụng
- 01 để biểu thị ngày trong tháng
- 02 để biểu thị tháng
- 03 để biểu thị giờ
- 04 để biểu thị phút
- 05 để biểu thị giây
- và còn nhiều hơn thế.
Bảng placeholder dưới đây mô tả phép ánh xạ chính xác. Go tiếp cận một cách hiệu quả hơn, khi bạn không cần phải nhớ hoặc tra cứu các mã định dạng truyền thống như trong các ngôn ngữ khác.
Type | Placeholder |
Day | 2 or 02 or _2 |
Day of Week | Monday or Mon |
Month | 01 or 1 or Jan or January |
Year | 2006 or 06 |
Hour | 03 or 3 or 15 |
Minutes | 04 or 4 |
Seconds | 05 or 5 |
Milli Seconds (ms) | .000 //Trailing zero will be includedor .999 //Trailing zero will be omitted |
Micro Seconds (μs) | .000000 //Trailing zero will be includedor .999999 //Trailing zero will be omitted |
Nano Seconds (ns) | .000000000 //Trailing zero will be includedor .999999999 //Trailing zero will be omitted |
am/pm | PM or pm |
Timezone | MST |
Timezone offset | Z0700 or Z070000 or Z07 or Z07:00 or Z07:00:00 or -0700 or -070000 or -07 or -07:00 or -07:00:00 |
Ví dụ phân tích cú pháp thời gian
Giờ quay lại với hàm time.Parse
. Chữ ký của hàm như sau:
func Parse(layout, value string) (Time, error)
Hàm time.Parse()
nhận vào hai tham số:
- Tham số đầu tiên là chuỗi định dạng của thời gian gồm các định dạng thay thế thời gian.
- Tham số thứ hai là chuỗi được định dạng thực tế đại diện cho một thời gian.
Cách tiếp cận của bạn là đảm bảo chuỗi định dạng (tham số đầu tiên) khớp với chuỗi biểu diễn (tham số thứ hai) của thời gian bạn muốn phân tích thành time.Time
. Để phân tích cú pháp
- Để phân tích cú pháp
2020-01-29
, chuỗi định dạng phải là06-01-02
hoặc2006-01-02
hoặc một cái gì đó phù hợp với bảng định dạng thay thế thời gian trên.
- Tương tự, để phân tích cú pháp "2020-Jan-29 Wednesday 12:19:25", chuỗi định dạng có thể là "2006-Jan-02 Monday 03:04:05"
Dưới đây là các ví dụ mã hoạt động của time.Parse().
package main
import (
"fmt"
"time"
)
func main() {
//Parse YYYY-MM-DD
timeT, _ := time.Parse("2006-01-02", "2020-01-29")
fmt.Println(timeT)
//Parse YY-MM-DD
timeT, _ = time.Parse("06-01-02", "20-01-29")
fmt.Println(timeT)
//Parse YYYY-#{MonthName}-DD
timeT, _ = time.Parse("2006-Jan-02", "2020-Jan-29")
fmt.Println(timeT)
//Parse YYYY-#{MonthName}-DD WeekDay HH:MM:SS
timeT, _ = time.Parse("2006-Jan-02 Monday 03:04:05", "2020-Jan-29 Wednesday 12:19:25")
fmt.Println(timeT)
//Parse YYYY-#{MonthName}-DD WeekDay HH:MM:SS PM Timezone TimezoneOffset
timeT, _ = time.Parse("2006-Jan-02 Monday 03:04:05 PM MST -07:00", "2020-Jan-29 Wednesday 12:19:25 AM IST +05:30")
fmt.Println(timeT)
}
Output:
2020-01-29 00:00:00 +0000 UTC
2020-01-29 00:00:00 +0000 UTC
2020-01-29 00:00:00 +0000 UTC
2020-01-29 12:19:25 +0000 UTC
2020-01-29 00:19:25 +0530 IST
Ví dụ định dạng thời gian
Hàm time.Format có thể được sử dụng để định dạng thời gian thành một chuỗi. Chữ ký của hàm như sau:
func (t Time) Format(layout string)
Dưới đây là một số ví dụ về mã định dạng thời gian
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
//Format YYYY-MM-DD
fmt.Printf("YYYY-MM-DD: %s\n", now.Format("2006-01-02"))
//Format YY-MM-DD
fmt.Printf("YY-MM-DD: %s\n", now.Format("06-01-02"))
//Format YYYY-#{MonthName}-DD
fmt.Printf("YYYY-#{MonthName}-DD: %s\n", now.Format("2006-Jan-02"))
//Format HH:MM:SS
fmt.Printf("HH:MM:SS: %s\n", now.Format("03:04:05"))
//Format HH:MM:SS Millisecond
fmt.Printf("HH:MM:SS Millisecond: %s\n", now.Format("03:04:05 .999"))
//Format YYYY-#{MonthName}-DD WeekDay HH:MM:SS
fmt.Printf("YYYY-#{MonthName}-DD WeekDay HH:MM:SS: %s\n", now.Format("2006-Jan-02 Monday 03:04:05"))
//Format YYYY-#{MonthName}-DD WeekDay HH:MM:SS PM Timezone TimezoneOffset
fmt.Printf("YYYY-#{MonthName}-DD WeekDay HH:MM:SS PM Timezone TimezoneOffset: %s\n", now.Format("2006-Jan-02 Monday 03:04:05 PM MST -07:00"))
}
Output:
YYYY-MM-DD: 2020-01-25
YY-MM-DD: 20-01-25
YYYY-#{MonthName}-DD: 2020-Jan-25
HH:MM:SS: 11:14:16
HH:MM:SS Millisecond: 11:14:16 .213
YYYY-#{MonthName}-DD WeekDay HH:MM:SS: 2020-Jan-25 Saturday 11:14:16
YYYY-#{MonthName}-DD WeekDay HH:MM:SS PM Timezone TimezoneOffset: 2020-Jan-25 Saturday 11:14:16 PM IST +05:30
Sự khác biệt thời gian
Phương thức Sub trong gói thời gian (time package) có thể được sử dụng để lấy sự khác biệt giữa hai giá trị thời gian khác nhau. Chữ ký của hàm là:
func (t Time) Sub(u Time) Duration
currentTime := time.Now()
oldTime := time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)
diff := currentTime.Sub(oldTime)
Chuyển đổi thời gian
Dưới đây là ví dụ về chuyển đổi giữa
- time.Time to Unix Timestamp
- Unix Timestamp to time.Time
package main
import (
"fmt"
"time"
)
func main() {
tNow := time.Now()
//time.Time to Unix Timestamp
tUnix := tNow.Unix()
fmt.Printf("timeUnix %d\n", tUnix)
//Unix Timestamp to time.Time
timeT := time.Unix(tUnix, 0)
fmt.Printf("time.Time: %s\n", timeT)
}
Output:
timeUnix 1257894000
time.Time: 2009-11-10 23:00:00 +0000 UTC
Chuyển đổi thời gian giữa các múi giờ khác nhau
Hàm In
trong package time
có thể được sử dụng để thay đổi location
liên quan đến đối tượng time.Time
cụ thể. Khi nào In
được gọi trên bất kỳ đối tượng time.Time
nào (ví dụ như t
) thì:
- Một bản sao của
t
được tạo ra đại diện cho cùng một thời điểm. - Vị trí của
t
được thiết lập thành vị trí được truyền vào hàmIn
để hiển thị. t
được trả về lại.
Hãy xem mã hoạt động dưới đây có thể được sử dụng để thay đổi giá trị vị trí liên quan đến một thời gian cụ thể.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
loc, _ := time.LoadLocation("UTC")
fmt.Printf("UTC Time: %s\n", now.In(loc))
loc, _ = time.LoadLocation("Europe/Berlin")
fmt.Printf("Berlin Time: %s\n", now.In(loc))
loc, _ = time.LoadLocation("America/New_York")
fmt.Printf("New York Time: %s\n", now.In(loc))
loc, _ = time.LoadLocation("Asia/Dubai")
fmt.Printf("Dubai Time: %s\n", now.In(loc))
}
Output:
UTC Time: 2020-01-31 18:09:41.705858 +0000 UTC
Berlin Time: 2020-01-31 19:09:41.705858 +0100 CET
New York Time: 2020-01-31 13:09:41.705858 -0500 EST
Dubai Time: 2020-01-31 22:09:41.705858 +0400 +04