// Package timezone 提供随计划冻结的时区快照,禁止读取宿主机或 ZONEINFO 环境配置。 package timezone import ( "archive/zip" "bytes" _ "embed" "errors" "io" "sync" "time" ) // Version 标识 Go 1.27.1 附带的 IANA 快照及文件摘要;升级时须保留旧版本可读能力。 const Version = "go1.27.1-b2d18a7c8fa8" //go:embed zoneinfo.zip var data []byte var zones sync.Map var archive = sync.OnceValues(func() (*zip.Reader, error) { return zip.NewReader(bytes.NewReader(data), int64(len(data))) }) // Load 仅接受精确的内置名称,返回只读 Location;不接受 Local 或文件系统路径。 func Load(name, version string) (*time.Location, error) { if version != Version || name == "" || name == "Local" || len(name) > 64 { return nil, errors.New("unsupported frozen timezone version or name") } if name == "UTC" { return time.UTC, nil } if v, ok := zones.Load(name); ok { return v.(*time.Location), nil } a, err := archive() if err != nil { return nil, err } for _, entry := range a.File { if entry.Name != name { continue } r, err := entry.Open() if err != nil { return nil, err } b, err := io.ReadAll(io.LimitReader(r, 1<<20)) closeErr := r.Close() if err != nil { return nil, err } if closeErr != nil { return nil, closeErr } loc, err := time.LoadLocationFromTZData(name, b) if err != nil { return nil, err } actual, _ := zones.LoadOrStore(name, loc) return actual.(*time.Location), nil } return nil, errors.New("unknown IANA timezone") }