不同系统的失去配置文件不同 以 centos为例
/etc/localtime -> /usr/share/zoneinfo/...
$ ls /etc/localtime -lh
/etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai
$ date -R
Fri, 12 Aug 2022 17:59:11 +0800
表示东八区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
dsn := "admin:admin@tcp(192.168.156.100:3306)/gorm?charset=utf8&parseTime=True&loc=Local"
/Users/zhangqian458/.gopath/src/github.com/go-sql-driver/mysql/packets.go
readRow() {
if !mc.parseTime {
continue
} else {
switch rows.rs.columns[i].fieldType {
case fieldTypeTimestamp, fieldTypeDateTime,
fieldTypeDate, fieldTypeNewDate:
dest[i], err = parseDateTime(
string(dest[i].([]byte)),
mc.cfg.Loc,
)
if err == nil {
continue
}
default:
continue
}
}
}
/src/github.com/go-sql-driver/mysql/utils.go
func parseDateTime(str string, loc *time.Location) (t time.Time, err error) {
base := "0000-00-00 00:00:00.0000000"
switch len(str) {
case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM"
if str == base[:len(str)] {
return
}
t, err = time.Parse(timeFormat[:len(str)], str)
default:
err = fmt.Errorf("invalid time string: %s", str)
return
}
// Adjust location
if err == nil && loc != time.UTC {
y, mo, d := t.Date()
h, mi, s := t.Clock()
t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
}
return
}
不指定就会使用默认的,默认的也就是local
上边中:
t, err = time.Parse(timeFormat[:len(str)], str)
func Parse(layout, value string) (Time, error) {
return parse(layout, value, UTC, Local)
}
// Local represents the system's local time zone.
// On Unix systems, Local consults the TZ environment
// variable to find the time zone to use. No TZ means
// use the system default /etc/localtime.
// TZ="" means use UTC.
// TZ="foo" means use file foo in the system timezone directory.
var Local *Location = &localLoc
source code
package main
import (
"encoding/json"
"time"
"github.com/zssky/log"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type TimeModel struct {
T *time.Time `gorm:default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;comment:'修改时间''"`
}
func (*TimeModel) TableName() string {
return "vvv"
}
func dbInit() (*gorm.DB, error) {
dsn := "admin:admin@tcp(192.168.156.100:3306)/gorm?charset=utf8&parseTime=True&loc=Local"
return gorm.Open(mysql.New(mysql.Config{
DSN: dsn, // DSN data source name
DefaultStringSize: 256, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &gorm.Config{})
}
func main() {
db, err := dbInit()
if err != nil {
log.Error(err)
return
}
r := TimeModel{}
if err = db.Model(&TimeModel{}).First(&r).Error; err != nil {
log.Error(err)
return
}
o, e := json.Marshal(r)
if e != nil {
log.Error(err)
return
}
log.Infof("%#v", *r.T)
log.Info(string(o))
}
时区信息在第一次使用时间是加载
go/src/time/zoneinfo_unix.go
func (l *Location) get() *Location {
if l == nil {
return &utcLoc
}
if l == &localLoc {
localOnce.Do(initLocal)
}
return l
}
// Many systems use /usr/share/zoneinfo, Solaris 2 has
// /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ.
var zoneSources = []string{
"/usr/share/zoneinfo/",
"/usr/share/lib/zoneinfo/",
"/usr/lib/locale/TZ/",
runtime.GOROOT() + "/lib/time/zoneinfo.zip",
}
func initLocal() {
// consult $TZ to find the time zone to use.
// no $TZ means use the system default /etc/localtime.
// $TZ="" means use UTC.
// $TZ="foo" or $TZ=":foo" if foo is an absolute path, then the file pointed
// by foo will be used to initialize timezone; otherwise, file
// /usr/share/zoneinfo/foo will be used.
tz, ok := syscall.Getenv("TZ")
switch {
case !ok:
z, err := loadLocation("localtime", []string{"/etc"})
if err == nil {
localLoc = *z
localLoc.name = "Local"
return
}
case tz != "":
if tz[0] == ':' {
tz = tz[1:]
}
if tz != "" && tz[0] == '/' {
if z, err := loadLocation(tz, []string{""}); err == nil {
localLoc = *z
if tz == "/etc/localtime" {
localLoc.name = "Local"
} else {
localLoc.name = tz
}
return
}
} else if tz != "" && tz != "UTC" {
if z, err := loadLocation(tz, zoneSources); err == nil {
localLoc = *z
return
}
}
}
// Fall back to UTC.
localLoc.name = "UTC"
}
系统调用
rt_sigaction(SIGRT_32, {sa_handler=0x463fe0, sa_mask=~[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_RESTART|SA_SIGINFO, sa_restorer=0x464120}, NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, ~[], [], 8) = 0
clone(child_stack=0xc00008e000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS, tls=0xc00007e090) = 245
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=244, si_uid=0} ---
rt_sigreturn({mask=[]}) = 0
--- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=244, si_uid=0} ---
rt_sigreturn({mask=[]}) = 0
--- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=244, si_uid=0} ---
rt_sigreturn({mask=[]}) = 10322680
rt_sigprocmask(SIG_SETMASK, ~[], [], 8) = 0
clone(child_stack=0xc000090000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS, tls=0xc00007e490) = 246
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
futex(0xc00007e548, FUTEX_WAKE_PRIVATE, 1) = 1
rt_sigprocmask(SIG_SETMASK, ~[], [], 8) = 0
clone(child_stack=0xc00008a000, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS, tls=0xc00007e890) = 248
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
fcntl(0, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE)
futex(0xc00007e948, FUTEX_WAKE_PRIVATE, 1) = 1
fcntl(1, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE)
fcntl(2, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE)
openat(AT_FDCWD, "/usr/share/zoneinfo//Asia/Shanghai", O_RDONLY) = 3
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\0\0\0\2\0\0\0\0"..., 4096) = 556
read(3, "", 4096) = 0
close(3) = 0
write(1, "2022/08/12 18:42:12 main.go:34: "..., 692022/08/12 18:42:12 main.go:34: info 0 "hello you see me"
) = 69
write(1, "2022/08/12 18:42:12 main.go:38: "..., 712022/08/12 18:42:12 main.go:38: info main "ttttttttttttttt"
) = 71
futex(0xc000100148, FUTEX_WAKE_PRIVATE, 1) = 1
socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("192.168.156.100")}, 16) = -1 EINPROGRESS (Operation now in progress)
epoll_create1(EPOLL_CLOEXEC) = 4
pipe2([5, 6], O_NONBLOCK|O_CLOEXEC) = 0
epoll_ctl(4, EPOLL_CTL_ADD, 5, {EPOLLIN, {u32=10511816, u64=10511816}}) = 0
epoll_ctl(4, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=2261080856, u64=140525001071384}}) = 0
epoll_pwait(4, [], 128, 0, NULL, 2) = 0
epoll_pwait(4, [{EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP|EPOLLRDHUP, {u32=2261080856, u64=140525001071384}}], 128, -1, NULL, 0) = 1
futex(0x9d83d8, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x9d82f8, FUTEX_WAKE_PRIVATE, 1) = 1
getsockopt(3, SOL_SOCKET, SO_ERROR, [110], [4]) = 0
epoll_ctl(4, EPOLL_CTL_DEL, 3, 0xc00015b04c) = 0
close(3) = 0
write(1, "\r\n2022/08/12 18:42:27 \33[35m/User"..., 219
2022/08/12 18:42:27 /Users/zhangqian458/git-jd/src/git.jd.com/drc/mytest/time/main.go:23
[error] failed to initialize database, got error dial tcp 192.168.156.100:3306: connect: connection timed out
) = 219
write(1, "2022/08/12 18:42:27 main.go:41: "..., 1172022/08/12 18:42:27 main.go:41: error main dial tcp 192.168.156.100:3306: connect: connection timed out
) = 117
exit_group(0) = ?
+++ exited with 0 +++
execve("/usr/bin/date", ["date"], [/* 22 vars */]) = 0
brk(NULL) = 0x1f63000
...
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=103860, ...}) = 0
mmap(NULL, 103860, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ff61912e000
close(3) = 0
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
fstat(3, {st_mode=S_IFREG|0644, st_size=2492, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff61914e000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2492
read(3, "", 4096) = 0
close(3) = 0
munmap(0x7ff61914e000, 4096) = 0
...
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=388, ...}) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=388, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff61914e000
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\0\0\0\2\0\0\0\0"..., 4096) = 388
lseek(3, -240, SEEK_CUR) = 148
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\0\3\0\0\0\0"..., 4096) = 240
close(3) = 0
munmap(0x7ff61914e000, 4096) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ff61914e000
write(1, "Fri Aug 12 18:00:25 CST 2022\n", 29Fri Aug 12 18:00:25 CST 2022
) = 29
close(1) = 0
munmap(0x7ff61914e000, 4096) = 0
close(2) = 0