zoneinfo_unix.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
  5. // Parse "zoneinfo" time zone file.
  6. // This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
  7. // See tzfile(5), http://en.wikipedia.org/wiki/Zoneinfo,
  8. // and ftp://munnari.oz.au/pub/oldtz/
  9. package time
  10. import (
  11. "errors"
  12. "runtime"
  13. "syscall"
  14. )
  15. func initTestingZone() {
  16. syscall.Setenv("TZ", "America/Los_Angeles")
  17. initLocal()
  18. }
  19. // Many systems use /usr/share/zoneinfo, Solaris 2 has
  20. // /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ.
  21. var zoneDirs = []string{
  22. "/usr/share/zoneinfo/",
  23. "/usr/share/lib/zoneinfo/",
  24. "/usr/lib/locale/TZ/",
  25. runtime.GOROOT() + "/lib/time/zoneinfo.zip",
  26. }
  27. var origZoneDirs = zoneDirs
  28. func forceZipFileForTesting(zipOnly bool) {
  29. zoneDirs = make([]string, len(origZoneDirs))
  30. copy(zoneDirs, origZoneDirs)
  31. if zipOnly {
  32. for i := 0; i < len(zoneDirs)-1; i++ {
  33. zoneDirs[i] = "/XXXNOEXIST"
  34. }
  35. }
  36. }
  37. func initLocal() {
  38. // consult $TZ to find the time zone to use.
  39. // no $TZ means use the system default /etc/localtime.
  40. // $TZ="" means use UTC.
  41. // $TZ="foo" means use /usr/share/zoneinfo/foo.
  42. tz, ok := syscall.Getenv("TZ")
  43. switch {
  44. case !ok:
  45. z, err := loadZoneFile("", "/etc/localtime")
  46. if err == nil {
  47. localLoc = *z
  48. localLoc.name = "Local"
  49. return
  50. }
  51. case tz != "" && tz != "UTC":
  52. if z, err := loadLocation(tz); err == nil {
  53. localLoc = *z
  54. return
  55. }
  56. }
  57. // Fall back to UTC.
  58. localLoc.name = "UTC"
  59. }
  60. func loadLocation(name string) (*Location, error) {
  61. for _, zoneDir := range zoneDirs {
  62. if z, err := loadZoneFile(zoneDir, name); err == nil {
  63. z.name = name
  64. return z, nil
  65. }
  66. }
  67. return nil, errors.New("unknown time zone " + name)
  68. }