Chromium Code Reviews| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 return FromJulianDay(Day(time) + kDayZeroInJulianDay).date; | 108 return FromJulianDay(Day(time) + kDayZeroInJulianDay).date; |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 // ECMA 262 - 15.9.1.9 | 112 // ECMA 262 - 15.9.1.9 |
| 113 function EquivalentYear(year) { | 113 function EquivalentYear(year) { |
| 114 // Returns an equivalent year in the range [2008-2035] matching | 114 // Returns an equivalent year in the range [2008-2035] matching |
| 115 // - leap year. | 115 // - leap year. |
| 116 // - week day of first day. | 116 // - week day of first day. |
| 117 var time = TimeFromYear(year); | 117 var time = TimeFromYear(year); |
| 118 var recent_year = (InLeapYear(time) == 0 ? 1967 : 1956) + | 118 var recent_year = (InLeapYear(time) == 0 ? 1967 : 1956) + |
| 119 (WeekDay(time) * 12) % 28; | 119 (WeekDay(time) * 12) % 28; |
| 120 // Find the year in the range 2008..2037 that is equivalent mod 28. | 120 // Find the year in the range 2008..2037 that is equivalent mod 28. |
| 121 // Add 3*28 to give a positive argument to the modulus operator. | 121 // Add 3*28 to give a positive argument to the modulus operator. |
| 122 return 2008 + (recent_year + 3*28 - 2008) % 28; | 122 return 2008 + (recent_year + 3*28 - 2008) % 28; |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 function EquivalentTime(t) { | 126 function EquivalentTime(t) { |
| 127 // The issue here is that some library calls don't work right for dates | 127 // The issue here is that some library calls don't work right for dates |
| 128 // that cannot be represented using a non-negative signed 32 bit integer | 128 // that cannot be represented using a non-negative signed 32 bit integer |
| 129 // (measured in whole seconds based on the 1970 epoch). | 129 // (measured in whole seconds based on the 1970 epoch). |
| 130 // We solve this by mapping the time to a year with same leap-year-ness | 130 // We solve this by mapping the time to a year with same leap-year-ness |
| 131 // and same starting day for the year. The ECMAscript specification says | 131 // and same starting day for the year. The ECMAscript specification says |
| 132 // we must do this, but for compatability with other browsers, we use | 132 // we must do this, but for compatibility with other browsers, we use |
| 133 // the actual year if it is in the range 1970..2037 | 133 // the actual year if it is in the range 1970..2037 |
| 134 if (t >= 0 && t <= 2.1e12) return t; | 134 if (t >= 0 && t <= 2.1e12) return t; |
| 135 var day = MakeDay(EquivalentYear(YearFromTime(t)), MonthFromTime(t), DateFromT ime(t)); | 135 var day = MakeDay(EquivalentYear(YearFromTime(t)), MonthFromTime(t), DateFromT ime(t)); |
| 136 return TimeClip(MakeDate(day, TimeWithinDay(t))); | 136 return TimeClip(MakeDate(day, TimeWithinDay(t))); |
| 137 } | 137 } |
| 138 | 138 |
| 139 var daylight_cache_time = $NaN; | 139 |
| 140 var daylight_cache_offset; | 140 // Because computing the DST offset is a pretty expensive operation |
| 141 // we keep a cache of last computed offset along with a time interval | |
| 142 // where we know the cache is valid. | |
| 143 var DST_offset_cache = { | |
| 144 // Cached DST offset. | |
| 145 offset: 0, | |
| 146 // Time interval where the cached offset is valid. | |
| 147 start: 0, end: -1, | |
| 148 // Size of next interval expansion. | |
| 149 increment: 0 | |
| 150 }; | |
| 151 | |
| 141 | 152 |
| 142 function DaylightSavingsOffset(t) { | 153 function DaylightSavingsOffset(t) { |
|
William Hesse
2009/06/16 07:11:29
Comment the function to state that the algorithm i
| |
| 143 if (t == daylight_cache_time) { | 154 // Load the cache object from the builtins object. |
| 144 return daylight_cache_offset; | 155 var cache = DST_offset_cache; |
| 156 | |
| 157 // Cache the start and the end in local variables for fast access. | |
| 158 var start = cache.start; | |
| 159 var end = cache.end; | |
| 160 | |
| 161 if (start <= t) { | |
| 162 // If the time fits in the cached interval, return the cached offset. | |
| 163 if (t <= end) return cache.offset; | |
| 164 | |
| 165 // Compute a possible new interval end. | |
| 166 var new_end = end + cache.increment; | |
| 167 | |
| 168 if (t <= new_end) { | |
| 169 var end_offset = %DateDaylightSavingsOffset(EquivalentTime(new_end)); | |
| 170 if (cache.offset == end_offset) { | |
| 171 // If the offset at the end of the new interval still matches | |
| 172 // the offset in the cache, we grow the cached time interval | |
| 173 // and return the offset. | |
| 174 cache.end = new_end; | |
| 175 cache.increment = msPerMonth; | |
| 176 return end_offset; | |
| 177 } else { | |
| 178 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); | |
| 179 if (offset == end_offset) { | |
| 180 // The offset at the given time is equal to the offset at the | |
| 181 // new end of the interval, so that means that we've just skipped | |
| 182 // the point in time where the DST offset change occurred. Updated | |
| 183 // the interval to reflect this and reset the increment. | |
| 184 cache.start = t; | |
| 185 cache.end = new_end; | |
| 186 cache.increment = msPerMonth; | |
| 187 } else { | |
| 188 // The interval contains a DST offset change and the given time is | |
| 189 // before it. Adjust the increment to avoid a linear search for | |
| 190 // the offset change point and change the end of the interval. | |
| 191 cache.increment /= 3; | |
| 192 cache.end = t; | |
| 193 } | |
| 194 // Update the offset in the cache and return it. | |
| 195 cache.offset = offset; | |
| 196 return offset; | |
| 197 } | |
| 198 } | |
| 145 } | 199 } |
| 200 | |
| 201 // Compute the DST offset for the time and shrink the cache interval | |
| 202 // to only contain the time. This allows fast repeated DST offset | |
| 203 // computations for the same time. | |
| 146 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); | 204 var offset = %DateDaylightSavingsOffset(EquivalentTime(t)); |
| 147 daylight_cache_time = t; | 205 cache.offset = offset; |
| 148 daylight_cache_offset = offset; | 206 cache.start = cache.end = t; |
| 207 cache.increment = msPerMonth; | |
| 149 return offset; | 208 return offset; |
| 150 } | 209 } |
| 151 | 210 |
| 152 | 211 |
| 153 var timezone_cache_time = $NaN; | 212 var timezone_cache_time = $NaN; |
| 154 var timezone_cache_timezone; | 213 var timezone_cache_timezone; |
| 155 | 214 |
| 156 function LocalTimezone(t) { | 215 function LocalTimezone(t) { |
| 157 if(t == timezone_cache_time) { | 216 if (t == timezone_cache_time) { |
| 158 return timezone_cache_timezone; | 217 return timezone_cache_timezone; |
| 159 } | 218 } |
| 160 var timezone = %DateLocalTimezone(EquivalentTime(t)); | 219 var timezone = %DateLocalTimezone(EquivalentTime(t)); |
| 161 timezone_cache_time = t; | 220 timezone_cache_time = t; |
| 162 timezone_cache_timezone = timezone; | 221 timezone_cache_timezone = timezone; |
| 163 return timezone; | 222 return timezone; |
| 164 } | 223 } |
| 165 | 224 |
| 166 | 225 |
| 167 function WeekDay(time) { | 226 function WeekDay(time) { |
| (...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1063 "toGMTString", DateToGMTString, | 1122 "toGMTString", DateToGMTString, |
| 1064 "toUTCString", DateToUTCString, | 1123 "toUTCString", DateToUTCString, |
| 1065 "getYear", DateGetYear, | 1124 "getYear", DateGetYear, |
| 1066 "setYear", DateSetYear, | 1125 "setYear", DateSetYear, |
| 1067 "toISOString", DateToISOString, | 1126 "toISOString", DateToISOString, |
| 1068 "toJSON", DateToJSON | 1127 "toJSON", DateToJSON |
| 1069 )); | 1128 )); |
| 1070 } | 1129 } |
| 1071 | 1130 |
| 1072 SetupDate(); | 1131 SetupDate(); |
| OLD | NEW |