1 // Copyright 2011 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.
5 // Parse Plan 9 timezone(2) files.
14 var zoneSources
= []string{
15 runtime
.GOROOT() + "/lib/time/zoneinfo.zip",
18 func isSpace(r rune
) bool {
19 return r
== ' ' || r
== '\t' || r
== '\n'
22 // Copied from strings to avoid a dependency.
23 func fields(s
string) []string {
24 // First count the fields.
27 for _
, rune
:= range s
{
29 inField
= !isSpace(rune
)
30 if inField
&& !wasInField
{
36 a
:= make([]string, n
)
38 fieldStart
:= -1 // Set to -1 when looking for start of field.
39 for i
, rune
:= range s
{
42 a
[na
] = s
[fieldStart
:i
]
46 } else if fieldStart
== -1 {
50 if fieldStart
>= 0 { // Last field might end at EOF.
51 a
[na
] = s
[fieldStart
:]
56 func loadZoneDataPlan9(s
string) (l
*Location
, err error
) {
59 if len(f
) == 2 && f
[0] == "GMT" {
67 // standard timezone offset
72 zones
[0] = zone
{name
: f
[0], offset
: o
, isDST
: false}
74 // alternate timezone offset
79 zones
[1] = zone
{name
: f
[2], offset
: o
, isDST
: true}
81 // transition time pairs
84 for i
:= 0; i
< len(f
); i
++ {
94 tx
= append(tx
, zoneTrans
{when
: int64(t
), index
: uint8(zi
)})
97 // Committed to succeed.
98 l
= &Location
{zone
: zones
[:], tx
: tx
}
100 // Fill in the cache with information about right now,
101 // since that will be the most common lookup.
104 if tx
[i
].when
<= sec
&& (i
+1 == len(tx
) || sec
< tx
[i
+1].when
) {
105 l
.cacheStart
= tx
[i
].when
108 l
.cacheEnd
= tx
[i
+1].when
110 l
.cacheZone
= &l
.zone
[tx
[i
].index
]
117 func loadZoneFilePlan9(name
string) (*Location
, error
) {
118 b
, err
:= readFile(name
)
122 return loadZoneDataPlan9(string(b
))
126 t
, ok
:= syscall
.Getenv("timezone")
128 if z
, err
:= loadZoneDataPlan9(t
); err
== nil {
133 if z
, err
:= loadZoneFilePlan9("/adm/timezone/local"); err
== nil {
135 localLoc
.name
= "Local"
141 localLoc
.name
= "UTC"