Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(271)

Delta Between Two Patch Sets: src/pkg/time/zoneinfo.go

Issue 5392041: code review 5392041: time: new Time, Duration, ZoneInfo types (Closed)
Left Patch Set: diff -r 6abf04c86097 https://go.googlecode.com/hg/ Created 13 years, 4 months ago
Right Patch Set: diff -r 3c286b9b2206 https://go.googlecode.com/hg/ Created 13 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/time/time_test.go ('k') | src/pkg/time/zoneinfo_plan9.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package time 5 package time
6 6
7 import "sync" 7 import "sync"
8 8
9 // A Location maps time instants to the zone in use at that time. 9 // A Location maps time instants to the zone in use at that time.
10 // Typically, the Location represents the collection of time offsets 10 // Typically, the Location represents the collection of time offsets
11 // in use in a geographical area, such as CEST and CET for central Europe. 11 // in use in a geographical area, such as CEST and CET for central Europe.
12 type Location struct { 12 type Location struct {
13 name string 13 name string
14 zone []zone 14 zone []zone
15 tx []zoneTrans 15 tx []zoneTrans
16 16
17 // Most lookups will be for the current time. 17 // Most lookups will be for the current time.
18 // To avoid the binary search through tx, keep a 18 // To avoid the binary search through tx, keep a
19 // static one-element cache that gives the correct 19 // static one-element cache that gives the correct
20 // zone for the time when the Location was created. 20 // zone for the time when the Location was created.
21 // if cacheStart <= t <= cacheEnd, 21 // if cacheStart <= t <= cacheEnd,
22 » // Lookup can return cacheZone. 22 » // lookup can return cacheZone.
23 // The units for cacheStart and cacheEnd are seconds 23 // The units for cacheStart and cacheEnd are seconds
24 // since January 1, 1970 UTC, to match the argument 24 // since January 1, 1970 UTC, to match the argument
25 » // to Lookup. 25 » // to lookup.
26 cacheStart int64 26 cacheStart int64
27 cacheEnd int64 27 cacheEnd int64
28 cacheZone *zone 28 cacheZone *zone
29 } 29 }
30 30
31 // A zone represents a single time zone such as EST or EDT. 31 // A zone represents a single time zone such as CEST or CET.
32 type zone struct { 32 type zone struct {
33 » name string // short name, "EST" 33 » name string // abbreviated name, "CET"
34 offset int // seconds east of UTC 34 offset int // seconds east of UTC
35 isDST bool // is this zone Daylight Savings Time? 35 isDST bool // is this zone Daylight Savings Time?
36 } 36 }
37 37
38 // A zoneTrans represents a single time zone transition. 38 // A zoneTrans represents a single time zone transition.
39 type zoneTrans struct { 39 type zoneTrans struct {
40 when int64 // transition time, in seconds since 1970 GMT 40 when int64 // transition time, in seconds since 1970 GMT
41 index uint8 // the index of the zone that goes into effect at tha t time 41 index uint8 // the index of the zone that goes into effect at tha t time
42 isstd, isutc bool // ignored - no idea what these mean 42 isstd, isutc bool // ignored - no idea what these mean
43 } 43 }
44 44
45 // UTC represents Universal Coordinated Time (UTC). 45 // UTC represents Universal Coordinated Time (UTC).
46 var UTC *Location = &utcLoc 46 var UTC *Location = &utcLoc
47 47
48 // utcLoc is separate so that get can refer to &utcLoc
49 // and ensure that it never returns a nil *Location,
50 // even if a badly behaved client has changed UTC.
48 var utcLoc = Location{name: "UTC"} 51 var utcLoc = Location{name: "UTC"}
49 52
50 // Local represents the system's local time zone. 53 // Local represents the system's local time zone.
51 var Local *Location = &localLoc 54 var Local *Location = &localLoc
52 55
56 // localLoc is separate so that initLocal can initialize
57 // it even if a client has changed Local.
53 var localLoc Location 58 var localLoc Location
54 var localOnce sync.Once 59 var localOnce sync.Once
55 60
56 func (l *Location) get() *Location { 61 func (l *Location) get() *Location {
57 if l == nil { 62 if l == nil {
58 return &utcLoc 63 return &utcLoc
59 } 64 }
60 if l == &localLoc { 65 if l == &localLoc {
61 localOnce.Do(initLocal) 66 localOnce.Do(initLocal)
62 } 67 }
63 return l 68 return l
64 } 69 }
65 70
66 // String returns a descriptive name for the time zone information, 71 // String returns a descriptive name for the time zone information,
67 // corresponding to the argument to LoadLocation. 72 // corresponding to the argument to LoadLocation.
68 func (l *Location) String() string { 73 func (l *Location) String() string {
69 return l.get().name 74 return l.get().name
70 } 75 }
71 76
72 // FixedZone returns a Location with a Lookup method 77 // FixedZone returns a Location that always uses
73 // that always returns the given name and offset. 78 // the given zone name and offset (seconds east of UTC).
74 func FixedZone(name string, offset int) *Location { 79 func FixedZone(name string, offset int) *Location {
75 l := &Location{ 80 l := &Location{
76 name: name, 81 name: name,
77 zone: []zone{{name, offset, false}}, 82 zone: []zone{{name, offset, false}},
78 tx: []zoneTrans{{-1 << 63, 0, false, false}}, 83 tx: []zoneTrans{{-1 << 63, 0, false, false}},
79 cacheStart: -1 << 63, 84 cacheStart: -1 << 63,
80 cacheEnd: 1<<63 - 1, 85 cacheEnd: 1<<63 - 1,
81 } 86 }
82 l.cacheZone = &l.zone[0] 87 l.cacheZone = &l.zone[0]
83 return l 88 return l
84 } 89 }
85 90
86 // Lookup returns information about the time zone in use at an 91 // lookup returns information about the time zone in use at an
87 // instant in time expressed as seconds since January 1, 1970 00:00:00 UTC. 92 // instant in time expressed as seconds since January 1, 1970 00:00:00 UTC.
88 // 93 //
89 // The returned information gives the name of the zone (such as "EST"), 94 // The returned information gives the name of the zone (such as "CET"),
90 // the start and end times bracketing sec when that zone is in effect, 95 // the start and end times bracketing sec when that zone is in effect,
91 // the offset in seconds east of UTC (such as -5*60*60), and whether 96 // the offset in seconds east of UTC (such as -5*60*60), and whether
92 // the daylight savings is being observed at that time. 97 // the daylight savings is being observed at that time.
93 func (l *Location) Lookup(sec int64) (name string, offset int, isDST bool, start , end int64) { 98 func (l *Location) lookup(sec int64) (name string, offset int, isDST bool, start , end int64) {
94 l = l.get() 99 l = l.get()
95 100
96 if len(l.tx) == 0 { 101 if len(l.tx) == 0 {
97 name = "UTC" 102 name = "UTC"
98 offset = 0 103 offset = 0
99 isDST = false 104 isDST = false
100 start = -1 << 63 105 start = -1 << 63
101 end = 1<<63 - 1 106 end = 1<<63 - 1
102 return 107 return
103 } 108 }
(...skipping 23 matching lines...) Expand all
127 } 132 }
128 zone := &l.zone[tx[0].index] 133 zone := &l.zone[tx[0].index]
129 name = zone.name 134 name = zone.name
130 offset = zone.offset 135 offset = zone.offset
131 isDST = zone.isDST 136 isDST = zone.isDST
132 start = tx[0].when 137 start = tx[0].when
133 // end = maintained during the search 138 // end = maintained during the search
134 return 139 return
135 } 140 }
136 141
137 // LookupName returns information about the time zone with 142 // lookupName returns information about the time zone with
138 // the given name (such as "EST"). 143 // the given name (such as "EST").
139 func (l *Location) LookupName(name string) (offset int, isDST bool, ok bool) { 144 func (l *Location) lookupName(name string) (offset int, isDST bool, ok bool) {
140 l = l.get() 145 l = l.get()
141 for i := range l.zone { 146 for i := range l.zone {
142 zone := &l.zone[i] 147 zone := &l.zone[i]
143 if zone.name == name { 148 if zone.name == name {
144 return zone.offset, zone.isDST, true 149 return zone.offset, zone.isDST, true
145 } 150 }
146 } 151 }
147 return 152 return
148 } 153 }
149 154
150 // LookupOffset returns information about the time zone with 155 // lookupOffset returns information about the time zone with
151 // the given offset (such as -5*60*60). 156 // the given offset (such as -5*60*60).
152 func (l *Location) LookupOffset(offset int) (name string, isDST bool, ok bool) { 157 func (l *Location) lookupOffset(offset int) (name string, isDST bool, ok bool) {
153 l = l.get() 158 l = l.get()
154 for i := range l.zone { 159 for i := range l.zone {
155 zone := &l.zone[i] 160 zone := &l.zone[i]
156 if zone.offset == offset { 161 if zone.offset == offset {
157 return zone.name, zone.isDST, true 162 return zone.name, zone.isDST, true
158 } 163 }
159 } 164 }
160 return 165 return
161 } 166 }
162 167
163 // NOTE(rsc): Eventually we will need to accept the POSIX TZ environment 168 // NOTE(rsc): Eventually we will need to accept the POSIX TZ environment
164 // syntax too, but I don't feel like implementing it today. 169 // syntax too, but I don't feel like implementing it today.
165 170
166 // NOTE(rsc): Using the IANA names below means ensuring we have access 171 // NOTE(rsc): Using the IANA names below means ensuring we have access
167 // to the database. Probably we will ship the files in $GOROOT/lib/zoneinfo/ 172 // to the database. Probably we will ship the files in $GOROOT/lib/zoneinfo/
168 // and only look there if there are no system files available (such as on Window s). 173 // and only look there if there are no system files available (such as on Window s).
169 // The files total 200 kB. 174 // The files total 200 kB.
170 175
171 // LoadLocation returns a Location describing the named location or time zone. 176 // LoadLocation returns the Location with the given name.
172 // 177 //
173 // If the name is "" or "UTC", LoadLocation returns UTC. 178 // If the name is "" or "UTC", LoadLocation returns UTC.
174 // If the name is "Local", LoadLocation returns Local. 179 // If the name is "Local", LoadLocation returns Local.
175 // 180 //
176 // Otherwise, the name is taken to be a location name corresponding to a file 181 // Otherwise, the name is taken to be a location name corresponding to a file
177 // in the IANA Time Zone database, such as "America/New_York". 182 // in the IANA Time Zone database, such as "America/New_York".
178 func LoadLocation(name string) (*Location, error) { 183 func LoadLocation(name string) (*Location, error) {
179 if name == "" || name == "UTC" { 184 if name == "" || name == "UTC" {
180 return UTC, nil 185 return UTC, nil
181 } 186 }
182 if name == "Local" { 187 if name == "Local" {
183 return Local, nil 188 return Local, nil
184 } 189 }
185 return loadLocation(name) 190 return loadLocation(name)
186 } 191 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b