SetTimeZone设置全局时区

package main

import (
	"fmt"
	"time"

	"github.com/gogf/gf/v2/os/gtime"
)

func main() {
	// 设置进程全局时区
	err := gtime.SetTimeZone("Asia/Tokyo")
	if err != nil {
		panic(err)
	}
	
	// 使用gtime获取当前时间
	fmt.Println(gtime.Now().String())

	// 使用标准库获取当前时间
	fmt.Println(time.Now().String())
}

执行后,输出结果为:

2023-01-06 15:27:38
2023-01-06 15:27:38.753909 +0900 JST m=+0.002758145

时区设置注意事项

SetTimeZone方法多次调用报错

SetTimeZone方法只允许全局设置一次时区,如果多次调用,并且设置的时区不一样,后续调用将会失败,并返回error

业务项目中,time包初始化问题

程序时区的全局设置必须要在标准库的timeimport之前调用,因为标准库的time包在import时会执行初始化,之后无法再全局修改程序时区,只能通过ToLocation方法(或者标准库In方法)对特定时间对象执行时区转换。对时间对象使用ToLocation转换的例子:

package main

import (
	"fmt"
	"time"

	"github.com/gogf/gf/v2/os/gtime"
)

func main() {
	// 设置进程全局时区
	err := gtime.SetTimeZone("Asia/Tokyo")
	if err != nil {
		panic(err)
	}

	// 使用gtime获取当前时间
	fmt.Println(gtime.Now())

	// 使用标准库获取当前时间
	fmt.Println(time.Now())

	// 对特定时间对象执行时区转换
	local, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		panic(err)
	}
	fmt.Println(gtime.Now().ToLocation(local))
}

执行后,终端输出:

2023-01-06 15:37:38
2023-01-06 15:37:38.753909 +0900 JST m=+0.002758145
2023-01-06 14:37:38

在业务项目中,往往在main包之前会有很多业务的包import,会引起time包的初始化问题。因此,如果需要全局设置时区,建议通过一个独立的包来调用SetTimeZone方法,并且在main包的最开头执行import规避time包初始化的问题。例如:

相关参考链接:https://stackoverflow.com/questions/54363451/setting-timezone-globally-in-golang


package main

import (
    _ "boot/time"

    "fmt"
	"time"
)

func main() {
	// 使用gtime获取当前时间
	fmt.Println(gtime.Now().String())

	// 使用标准库获取当前时间
	fmt.Println(time.Now().String())
}