Go语言的time包提供了时间的显示和测量功能,日历计算采用公历。
time.Time表示时间点time.Duration表示时间段,单位纳秒场景:订单管理系统中的时间处理
package main
import (
"fmt"
"time"
)
// 订单结构
type Order struct {
ID string
Customer string
Amount float64
Status string
CreatedAt time.Time
UpdatedAt time.Time
PaidAt *time.Time
}
// 创建新订单
func createOrder(id, customer string, amount float64) *Order {
now := time.Now()
return &Order{
ID: id,
Customer: customer,
Amount: amount,
Status: "created",
CreatedAt: now,
UpdatedAt: now,
}
}
// 标记订单为已支付
func (o *Order) markAsPaid() {
now := time.Now()
o.Status = "paid"
o.PaidAt = &now
o.UpdatedAt = now
}
// 计算处理时长
func (o *Order) processingDuration() time.Duration {
endTime := time.Now()
if o.PaidAt != nil {
endTime = *o.PaidAt
}
return endTime.Sub(o.CreatedAt)
}
// 检查订单是否超时(15分钟未支付)
func (o *Order) isTimeout() bool {
if o.Status == "paid" {
return false
}
timeout := o.CreatedAt.Add(15 * time.Minute)
return time.Now().After(timeout)
}
func main() {
// 创建订单
order := createOrder("ORD-2023-001", "张三", 299.99)
fmt.Printf("订单创建时间: %s\n", order.CreatedAt.Format("2006-01-02 15:04:05"))
// 模拟5秒后支付
time.Sleep(2 * time.Second) // 实际使用中不需要sleep,这里为了演示
order.markAsPaid()
if order.PaidAt != nil {
fmt.Printf("订单支付时间: %s\n", order.PaidAt.Format("2006-01-02 15:04:05"))
}
// 计算处理时长
duration := order.processingDuration()
fmt.Printf("订单处理时长: %v\n", duration)
fmt.Printf("订单处理时长(秒): %.2f秒\n", duration.Seconds())
// 检查超时
fmt.Printf("订单是否超时: %t\n", order.isTimeout())
// 定时任务:模拟订单状态监控
fmt.Println("\n启动订单监控...")
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
timeoutChan := time.After(25 * time.Second) // 25秒后停止演示
for {
select {
case <-ticker.C:
// 检查新订单是否超时(模拟)
newOrder := createOrder(fmt.Sprintf("ORD-%d", time.Now().Unix()), "李四", 199.99)
// 模拟一些订单在超时边缘
if time.Now().Second()%2 == 0 {
fmt.Printf("[%s] 新订单 %s 创建, 状态: %s\n",
time.Now().Format("15:04:05"), newOrder.ID, newOrder.Status)
}
case <-timeoutChan:
fmt.Println("监控停止")
break monitor
}
}
// 时间计算演示
now := time.Now()
fmt.Printf("\n时间计算演示:\n")
fmt.Printf("当前时间: %s\n", now.Format("2006-01-02 15:04:05"))
fmt.Printf("一周后: %s\n", now.AddDate(0, 0, 7).Format("2006-01-02"))
fmt.Printf("3小时前: %s\n", now.Add(-3*time.Hour).Format("15:04:05"))
fmt.Printf("本月最后一天: %s\n",
time.Date(now.Year(), now.Month()+1, 0, 0, 0, 0, 0, now.Location()).Format("2006-01-02"))
}
package main
import (
"fmt"
"time"
)
func main() {
// 1. 时间解析和格式化
timeStr := "2023-08-15 14:30:25"
layout := "2006-01-02 15:04:05"
parsedTime, err := time.Parse(layout, timeStr)
if err != nil {
fmt.Println("时间解析错误:", err)
} else {
fmt.Printf("解析的时间: %s\n", parsedTime.Format("2006年01月02日 15点04分"))
}
// 2. 时区处理
loc, _ := time.LoadLocation("America/New_York")
nyTime := time.Now().In(loc)
fmt.Printf("纽约时间: %s\n", nyTime.Format("2006-01-02 15:04:05 MST"))
// 3. 时间比较
time1 := time.Now()
time2 := time1.Add(2 * time.Hour)
fmt.Printf("\n时间比较:\n")
fmt.Printf("time1 在 time2 之前: %t\n", time1.Before(time2))
fmt.Printf("time1 在 time2 之后: %t\n", time1.After(time2))
fmt.Printf("时间相等: %t\n", time1.Equal(time1))
// 4. 时间周期计算
start := time.Date(2023, 1, 1, 0, 0, 0, 0, time.Local)
end := time.Date(2023, 12, 31, 23, 59, 59, 0, time.Local)
days := end.Sub(start).Hours() / 24
fmt.Printf("\n2023年共 %.0f 天\n", days)
// 5. 定时器和超时控制
fmt.Println("\n启动超时演示...")
// 模拟耗时操作
done := make(chan bool)
go func() {
time.Sleep(3 * time.Second) // 模拟工作
done <- true
}()
select {
case <-done:
fmt.Println("操作完成!")
case <-time.After(2 * time.Second): // 2秒超时
fmt.Println("操作超时!")
}
// 6. 生日计算
birthday := time.Date(1990, time.October, 5, 0, 0, 0, 0, time.Local)
age := now.Year() - birthday.Year()
// 如果今年生日还没到,年龄减1
if now.YearDay() < birthday.YearDay() {
age--
}
nextBirthday := time.Date(now.Year(), birthday.Month(), birthday.Day(), 0, 0, 0, 0, time.Local)
if now.After(nextBirthday) {
nextBirthday = nextBirthday.AddDate(1, 0, 0)
}
daysToBirthday := int(nextBirthday.Sub(now).Hours() / 24)
fmt.Printf("\n年龄: %d岁\n", age)
fmt.Printf("距离下次生日还有 %d 天\n", daysToBirthday)
}
time.Now()获取当前时间,time.Time表示时间点time.Duration表示时间段,支持纳秒精度time.Tick和time.Ticker用于定时任务time.Parse和time.ParseInLocation解析字符串时间