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 |