OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 // Because computing the DST offset is an expensive operation, | 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 | 131 // we keep a cache of the last computed DST offset along with a time interval |
132 // where we know the cache is valid. | 132 // where we know the cache is valid. |
133 // When the cache is valid, local_time_offset is also valid. | 133 // When the cache is valid, local_time_offset is also valid. |
134 var DST_offset_cache = { | 134 var DST_offset_cache = { |
135 // Cached DST offset. | 135 // Cached DST offset. |
136 offset: 0, | 136 offset: 0, |
137 // Time interval where the cached offset is valid. | 137 // Time interval where the cached offset is valid. |
138 start: 0, end: -1, | 138 start: 0, end: -1, |
139 // Size of next interval expansion. | 139 // Size of next interval expansion. |
140 increment: 0 | 140 increment: 0, |
| 141 initial_increment: 19 * msPerDay |
141 }; | 142 }; |
142 | 143 |
143 | 144 |
144 // NOTE: The implementation relies on the fact that no time zones have | 145 // NOTE: The implementation relies on the fact that no time zones have |
145 // more than one daylight savings offset change per month. | 146 // more than one daylight savings offset change per 19 days. |
| 147 // |
| 148 // In Egypt in 2010 they decided to suspend DST during Ramadan. This |
| 149 // led to a short interval where DST is in effect from September 10 to |
| 150 // September 30. |
| 151 // |
146 // If this function is called with NaN it returns NaN. | 152 // If this function is called with NaN it returns NaN. |
147 function DaylightSavingsOffset(t) { | 153 function DaylightSavingsOffset(t) { |
148 // Load the cache object from the builtins object. | 154 // Load the cache object from the builtins object. |
149 var cache = DST_offset_cache; | 155 var cache = DST_offset_cache; |
150 | 156 |
151 // Cache the start and the end in local variables for fast access. | 157 // Cache the start and the end in local variables for fast access. |
152 var start = cache.start; | 158 var start = cache.start; |
153 var end = cache.end; | 159 var end = cache.end; |
154 | 160 |
155 if (start <= t) { | 161 if (start <= t) { |
156 // If the time fits in the cached interval, return the cached offset. | 162 // If the time fits in the cached interval, return the cached offset. |
157 if (t <= end) return cache.offset; | 163 if (t <= end) return cache.offset; |
158 | 164 |
159 // If the cache misses, the local_time_offset may not be initialized. | 165 // If the cache misses, the local_time_offset may not be initialized. |
160 if (IS_UNDEFINED(local_time_offset)) { | 166 if (IS_UNDEFINED(local_time_offset)) { |
161 local_time_offset = %DateLocalTimeOffset(); | 167 local_time_offset = %DateLocalTimeOffset(); |
162 } | 168 } |
163 | 169 |
164 // Compute a possible new interval end. | 170 // Compute a possible new interval end. |
165 var new_end = end + cache.increment; | 171 var new_end = end + cache.increment; |
166 | 172 |
167 if (t <= new_end) { | 173 if (t <= new_end) { |
168 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end)); | 174 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end)); |
169 if (cache.offset == end_offset) { | 175 if (cache.offset == end_offset) { |
170 // If the offset at the end of the new interval still matches | 176 // If the offset at the end of the new interval still matches |
171 // the offset in the cache, we grow the cached time interval | 177 // the offset in the cache, we grow the cached time interval |
172 // and return the offset. | 178 // and return the offset. |
173 cache.end = new_end; | 179 cache.end = new_end; |
174 cache.increment = msPerMonth; | 180 cache.increment = cache.initial_increment; |
175 return end_offset; | 181 return end_offset; |
176 } else { | 182 } else { |
177 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); | 183 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); |
178 if (offset == end_offset) { | 184 if (offset == end_offset) { |
179 // The offset at the given time is equal to the offset at the | 185 // The offset at the given time is equal to the offset at the |
180 // new end of the interval, so that means that we've just skipped | 186 // new end of the interval, so that means that we've just skipped |
181 // the point in time where the DST offset change occurred. Updated | 187 // the point in time where the DST offset change occurred. Updated |
182 // the interval to reflect this and reset the increment. | 188 // the interval to reflect this and reset the increment. |
183 cache.start = t; | 189 cache.start = t; |
184 cache.end = new_end; | 190 cache.end = new_end; |
185 cache.increment = msPerMonth; | 191 cache.increment = cache.initial_increment; |
186 } else { | 192 } else { |
187 // The interval contains a DST offset change and the given time is | 193 // The interval contains a DST offset change and the given time is |
188 // before it. Adjust the increment to avoid a linear search for | 194 // before it. Adjust the increment to avoid a linear search for |
189 // the offset change point and change the end of the interval. | 195 // the offset change point and change the end of the interval. |
190 cache.increment /= 3; | 196 cache.increment /= 3; |
191 cache.end = t; | 197 cache.end = t; |
192 } | 198 } |
193 // Update the offset in the cache and return it. | 199 // Update the offset in the cache and return it. |
194 cache.offset = offset; | 200 cache.offset = offset; |
195 return offset; | 201 return offset; |
196 } | 202 } |
197 } | 203 } |
198 } | 204 } |
199 | 205 |
200 // If the cache misses, the local_time_offset may not be initialized. | 206 // If the cache misses, the local_time_offset may not be initialized. |
201 if (IS_UNDEFINED(local_time_offset)) { | 207 if (IS_UNDEFINED(local_time_offset)) { |
202 local_time_offset = %DateLocalTimeOffset(); | 208 local_time_offset = %DateLocalTimeOffset(); |
203 } | 209 } |
204 // Compute the DST offset for the time and shrink the cache interval | 210 // Compute the DST offset for the time and shrink the cache interval |
205 // to only contain the time. This allows fast repeated DST offset | 211 // to only contain the time. This allows fast repeated DST offset |
206 // computations for the same time. | 212 // computations for the same time. |
207 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); | 213 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); |
208 cache.offset = offset; | 214 cache.offset = offset; |
209 cache.start = cache.end = t; | 215 cache.start = cache.end = t; |
210 cache.increment = msPerMonth; | 216 cache.increment = cache.initial_increment; |
211 return offset; | 217 return offset; |
212 } | 218 } |
213 | 219 |
214 | 220 |
215 var timezone_cache_time = $NaN; | 221 var timezone_cache_time = $NaN; |
216 var timezone_cache_timezone; | 222 var timezone_cache_timezone; |
217 | 223 |
218 function LocalTimezone(t) { | 224 function LocalTimezone(t) { |
219 if (NUMBER_IS_NAN(t)) return ""; | 225 if (NUMBER_IS_NAN(t)) return ""; |
220 if (t == timezone_cache_time) { | 226 if (t == timezone_cache_time) { |
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 "toGMTString", DateToGMTString, | 1056 "toGMTString", DateToGMTString, |
1051 "toUTCString", DateToUTCString, | 1057 "toUTCString", DateToUTCString, |
1052 "getYear", DateGetYear, | 1058 "getYear", DateGetYear, |
1053 "setYear", DateSetYear, | 1059 "setYear", DateSetYear, |
1054 "toISOString", DateToISOString, | 1060 "toISOString", DateToISOString, |
1055 "toJSON", DateToJSON | 1061 "toJSON", DateToJSON |
1056 )); | 1062 )); |
1057 } | 1063 } |
1058 | 1064 |
1059 SetupDate(); | 1065 SetupDate(); |
OLD | NEW |