| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 // the actual year if it is in the range 1970..2037 | 114 // the actual year if it is in the range 1970..2037 |
| 115 if (t >= 0 && t <= 2.1e12) return t; | 115 if (t >= 0 && t <= 2.1e12) return t; |
| 116 | 116 |
| 117 var day = MakeDay(EquivalentYear(YEAR_FROM_TIME(t)), | 117 var day = MakeDay(EquivalentYear(YEAR_FROM_TIME(t)), |
| 118 MONTH_FROM_TIME(t), | 118 MONTH_FROM_TIME(t), |
| 119 DATE_FROM_TIME(t)); | 119 DATE_FROM_TIME(t)); |
| 120 return MakeDate(day, TimeWithinDay(t)); | 120 return MakeDate(day, TimeWithinDay(t)); |
| 121 } | 121 } |
| 122 | 122 |
| 123 | 123 |
| 124 // Because computing the DST offset is a pretty expensive operation | 124 // local_time_offset is initialized when the DST_offset_cache is missed. |
| 125 // we keep a cache of last computed offset along with a time interval | 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 |
| 126 // 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. |
| 127 var DST_offset_cache = { | 134 var DST_offset_cache = { |
| 128 // Cached DST offset. | 135 // Cached DST offset. |
| 129 offset: 0, | 136 offset: 0, |
| 130 // Time interval where the cached offset is valid. | 137 // Time interval where the cached offset is valid. |
| 131 start: 0, end: -1, | 138 start: 0, end: -1, |
| 132 // Size of next interval expansion. | 139 // Size of next interval expansion. |
| 133 increment: 0 | 140 increment: 0 |
| 134 }; | 141 }; |
| 135 | 142 |
| 136 | 143 |
| 137 // NOTE: The implementation relies on the fact that no time zones have | 144 // NOTE: The implementation relies on the fact that no time zones have |
| 138 // more than one daylight savings offset change per month. | 145 // more than one daylight savings offset change per month. |
| 139 // If this function is called with NaN it returns NaN. | 146 // If this function is called with NaN it returns NaN. |
| 140 function DaylightSavingsOffset(t) { | 147 function DaylightSavingsOffset(t) { |
| 141 // Load the cache object from the builtins object. | 148 // Load the cache object from the builtins object. |
| 142 var cache = DST_offset_cache; | 149 var cache = DST_offset_cache; |
| 143 | 150 |
| 144 // Cache the start and the end in local variables for fast access. | 151 // Cache the start and the end in local variables for fast access. |
| 145 var start = cache.start; | 152 var start = cache.start; |
| 146 var end = cache.end; | 153 var end = cache.end; |
| 147 | 154 |
| 148 if (start <= t) { | 155 if (start <= t) { |
| 149 // If the time fits in the cached interval, return the cached offset. | 156 // If the time fits in the cached interval, return the cached offset. |
| 150 if (t <= end) return cache.offset; | 157 if (t <= end) return cache.offset; |
| 151 | 158 |
| 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 |
| 152 // Compute a possible new interval end. | 164 // Compute a possible new interval end. |
| 153 var new_end = end + cache.increment; | 165 var new_end = end + cache.increment; |
| 154 | 166 |
| 155 if (t <= new_end) { | 167 if (t <= new_end) { |
| 156 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end)); | 168 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end)); |
| 157 if (cache.offset == end_offset) { | 169 if (cache.offset == end_offset) { |
| 158 // If the offset at the end of the new interval still matches | 170 // If the offset at the end of the new interval still matches |
| 159 // the offset in the cache, we grow the cached time interval | 171 // the offset in the cache, we grow the cached time interval |
| 160 // and return the offset. | 172 // and return the offset. |
| 161 cache.end = new_end; | 173 cache.end = new_end; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 178 cache.increment /= 3; | 190 cache.increment /= 3; |
| 179 cache.end = t; | 191 cache.end = t; |
| 180 } | 192 } |
| 181 // Update the offset in the cache and return it. | 193 // Update the offset in the cache and return it. |
| 182 cache.offset = offset; | 194 cache.offset = offset; |
| 183 return offset; | 195 return offset; |
| 184 } | 196 } |
| 185 } | 197 } |
| 186 } | 198 } |
| 187 | 199 |
| 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 } |
| 188 // Compute the DST offset for the time and shrink the cache interval | 204 // Compute the DST offset for the time and shrink the cache interval |
| 189 // to only contain the time. This allows fast repeated DST offset | 205 // to only contain the time. This allows fast repeated DST offset |
| 190 // computations for the same time. | 206 // computations for the same time. |
| 191 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); | 207 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); |
| 192 cache.offset = offset; | 208 cache.offset = offset; |
| 193 cache.start = cache.end = t; | 209 cache.start = cache.end = t; |
| 194 cache.increment = msPerMonth; | 210 cache.increment = msPerMonth; |
| 195 return offset; | 211 return offset; |
| 196 } | 212 } |
| 197 | 213 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 208 timezone_cache_time = t; | 224 timezone_cache_time = t; |
| 209 timezone_cache_timezone = timezone; | 225 timezone_cache_timezone = timezone; |
| 210 return timezone; | 226 return timezone; |
| 211 } | 227 } |
| 212 | 228 |
| 213 | 229 |
| 214 function WeekDay(time) { | 230 function WeekDay(time) { |
| 215 return Modulo(DAY(time) + 4, 7); | 231 return Modulo(DAY(time) + 4, 7); |
| 216 } | 232 } |
| 217 | 233 |
| 218 var local_time_offset = %DateLocalTimeOffset(); | |
| 219 | 234 |
| 220 function LocalTime(time) { | 235 function LocalTime(time) { |
| 221 if (NUMBER_IS_NAN(time)) return time; | 236 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; |
| 223 } | 239 } |
| 224 | 240 |
| 225 function LocalTimeNoCheck(time) { | 241 function LocalTimeNoCheck(time) { |
| 226 if (time < -MAX_TIME_MS || time > MAX_TIME_MS) { | 242 if (time < -MAX_TIME_MS || time > MAX_TIME_MS) { |
| 227 return $NaN; | 243 return $NaN; |
| 228 } | 244 } |
| 229 | 245 |
| 230 // Inline the DST offset cache checks for speed. | 246 // Inline the DST offset cache checks for speed. |
| 247 // The cache is hit, or DaylightSavingsOffset is called, |
| 248 // before local_time_offset is used. |
| 231 var cache = DST_offset_cache; | 249 var cache = DST_offset_cache; |
| 232 if (cache.start <= time && time <= cache.end) { | 250 if (cache.start <= time && time <= cache.end) { |
| 233 var dst_offset = cache.offset; | 251 var dst_offset = cache.offset; |
| 234 } else { | 252 } else { |
| 235 var dst_offset = DaylightSavingsOffset(time); | 253 var dst_offset = DaylightSavingsOffset(time); |
| 236 } | 254 } |
| 237 return time + local_time_offset + dst_offset; | 255 return time + local_time_offset + dst_offset; |
| 238 } | 256 } |
| 239 | 257 |
| 240 | 258 |
| 241 function UTC(time) { | 259 function UTC(time) { |
| 242 if (NUMBER_IS_NAN(time)) return time; | 260 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 } |
| 243 var tmp = time - local_time_offset; | 266 var tmp = time - local_time_offset; |
| 244 return tmp - DaylightSavingsOffset(tmp); | 267 return tmp - DaylightSavingsOffset(tmp); |
| 245 } | 268 } |
| 246 | 269 |
| 247 | 270 |
| 248 // ECMA 262 - 15.9.1.11 | 271 // ECMA 262 - 15.9.1.11 |
| 249 function MakeTime(hour, min, sec, ms) { | 272 function MakeTime(hour, min, sec, ms) { |
| 250 if (!$isFinite(hour)) return $NaN; | 273 if (!$isFinite(hour)) return $NaN; |
| 251 if (!$isFinite(min)) return $NaN; | 274 if (!$isFinite(min)) return $NaN; |
| 252 if (!$isFinite(sec)) return $NaN; | 275 if (!$isFinite(sec)) return $NaN; |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 | 582 |
| 560 function TimeString(time) { | 583 function TimeString(time) { |
| 561 return TwoDigitString(HOUR_FROM_TIME(time)) + ':' | 584 return TwoDigitString(HOUR_FROM_TIME(time)) + ':' |
| 562 + TwoDigitString(MIN_FROM_TIME(time)) + ':' | 585 + TwoDigitString(MIN_FROM_TIME(time)) + ':' |
| 563 + TwoDigitString(SEC_FROM_TIME(time)); | 586 + TwoDigitString(SEC_FROM_TIME(time)); |
| 564 } | 587 } |
| 565 | 588 |
| 566 | 589 |
| 567 function LocalTimezoneString(time) { | 590 function LocalTimezoneString(time) { |
| 568 var timezoneOffset = | 591 var timezoneOffset = |
| 569 (local_time_offset + DaylightSavingsOffset(time)) / msPerMinute; | 592 (DaylightSavingsOffset(time) + local_time_offset) / msPerMinute; |
| 570 var sign = (timezoneOffset >= 0) ? 1 : -1; | 593 var sign = (timezoneOffset >= 0) ? 1 : -1; |
| 571 var hours = FLOOR((sign * timezoneOffset)/60); | 594 var hours = FLOOR((sign * timezoneOffset)/60); |
| 572 var min = FLOOR((sign * timezoneOffset)%60); | 595 var min = FLOOR((sign * timezoneOffset)%60); |
| 573 var gmt = ' GMT' + ((sign == 1) ? '+' : '-') + | 596 var gmt = ' GMT' + ((sign == 1) ? '+' : '-') + |
| 574 TwoDigitString(hours) + TwoDigitString(min); | 597 TwoDigitString(hours) + TwoDigitString(min); |
| 575 return gmt + ' (' + LocalTimezone(time) + ')'; | 598 return gmt + ' (' + LocalTimezone(time) + ')'; |
| 576 } | 599 } |
| 577 | 600 |
| 578 | 601 |
| 579 function DatePrintString(time) { | 602 function DatePrintString(time) { |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 "toGMTString", DateToGMTString, | 1104 "toGMTString", DateToGMTString, |
| 1082 "toUTCString", DateToUTCString, | 1105 "toUTCString", DateToUTCString, |
| 1083 "getYear", DateGetYear, | 1106 "getYear", DateGetYear, |
| 1084 "setYear", DateSetYear, | 1107 "setYear", DateSetYear, |
| 1085 "toISOString", DateToISOString, | 1108 "toISOString", DateToISOString, |
| 1086 "toJSON", DateToJSON | 1109 "toJSON", DateToJSON |
| 1087 )); | 1110 )); |
| 1088 } | 1111 } |
| 1089 | 1112 |
| 1090 SetupDate(); | 1113 SetupDate(); |
| OLD | NEW |