@@ -121,9 +121,16 @@ function EquivalentTime(t) {
121121}
122122
123123
124- // Because computing the DST offset is a pretty expensive operation
125- // we keep a cache of last computed offset along with a time interval
124+ // local_time_offset is initialized when the DST_offset_cache is missed.
125+ // It must not be used until after a call to DaylightSavingsOffset().
126+ // In this way, only one check, for a DST cache miss, is needed.
127+ var local_time_offset ;
128+
129+
130+ // Because computing the DST offset is an expensive operation,
131+ // we keep a cache of the last computed DST offset along with a time interval
126132// where we know the cache is valid.
133+ // When the cache is valid, local_time_offset is also valid.
127134var DST_offset_cache = {
128135 // Cached DST offset.
129136 offset : 0 ,
@@ -149,6 +156,11 @@ function DaylightSavingsOffset(t) {
149156 // If the time fits in the cached interval, return the cached offset.
150157 if ( t <= end ) return cache . offset ;
151158
159+ // If the cache misses, the local_time_offset may not be initialized.
160+ if ( IS_UNDEFINED ( local_time_offset ) ) {
161+ local_time_offset = % DateLocalTimeOffset ( ) ;
162+ }
163+
152164 // Compute a possible new interval end.
153165 var new_end = end + cache . increment ;
154166
@@ -185,6 +197,10 @@ function DaylightSavingsOffset(t) {
185197 }
186198 }
187199
200+ // If the cache misses, the local_time_offset may not be initialized.
201+ if ( IS_UNDEFINED ( local_time_offset ) ) {
202+ local_time_offset = % DateLocalTimeOffset ( ) ;
203+ }
188204 // Compute the DST offset for the time and shrink the cache interval
189205 // to only contain the time. This allows fast repeated DST offset
190206 // computations for the same time.
@@ -215,11 +231,11 @@ function WeekDay(time) {
215231 return Modulo ( DAY ( time ) + 4 , 7 ) ;
216232}
217233
218- var local_time_offset = % DateLocalTimeOffset ( ) ;
219234
220235function LocalTime ( time ) {
221236 if ( NUMBER_IS_NAN ( time ) ) return time ;
222- return time + local_time_offset + DaylightSavingsOffset ( time ) ;
237+ // DaylightSavingsOffset called before local_time_offset used.
238+ return time + DaylightSavingsOffset ( time ) + local_time_offset ;
223239}
224240
225241function LocalTimeNoCheck ( time ) {
@@ -228,6 +244,8 @@ function LocalTimeNoCheck(time) {
228244 }
229245
230246 // Inline the DST offset cache checks for speed.
247+ // The cache is hit, or DaylightSavingsOffset is called,
248+ // before local_time_offset is used.
231249 var cache = DST_offset_cache ;
232250 if ( cache . start <= time && time <= cache . end ) {
233251 var dst_offset = cache . offset ;
@@ -240,6 +258,11 @@ function LocalTimeNoCheck(time) {
240258
241259function UTC ( time ) {
242260 if ( NUMBER_IS_NAN ( time ) ) return time ;
261+ // local_time_offset is needed before the call to DaylightSavingsOffset,
262+ // so it may be uninitialized.
263+ if ( IS_UNDEFINED ( local_time_offset ) ) {
264+ local_time_offset = % DateLocalTimeOffset ( ) ;
265+ }
243266 var tmp = time - local_time_offset ;
244267 return tmp - DaylightSavingsOffset ( tmp ) ;
245268}
@@ -566,7 +589,7 @@ function TimeString(time) {
566589
567590function LocalTimezoneString ( time ) {
568591 var timezoneOffset =
569- ( local_time_offset + DaylightSavingsOffset ( time ) ) / msPerMinute ;
592+ ( DaylightSavingsOffset ( time ) + local_time_offset ) / msPerMinute ;
570593 var sign = ( timezoneOffset >= 0 ) ? 1 : - 1 ;
571594 var hours = FLOOR ( ( sign * timezoneOffset ) / 60 ) ;
572595 var min = FLOOR ( ( sign * timezoneOffset ) % 60 ) ;
0 commit comments