Changeset 251852 in webkit
- Timestamp:
- Oct 31, 2019 9:14:03 AM (5 years ago)
- Location:
- trunk/Source
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r251834 r251852 1 2019-10-31 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] DateMath should have TimeClipped version 4 https://bugs.webkit.org/show_bug.cgi?id=203550 5 6 Reviewed by Saam Barati. 7 8 Removing `using namespace WTF;` in Date related files in JSC. 9 10 * runtime/DateConstructor.cpp: 11 * runtime/DateConversion.cpp: 12 (JSC::formatDateTime): 13 * runtime/DateInstance.cpp: 14 * runtime/DatePrototype.cpp: 15 * runtime/JSDateMath.cpp: 16 (JSC::localTimeOffset): 17 (JSC::timeToMS): 18 (JSC::gregorianDateTimeToMS): 19 (JSC::msToGregorianDateTime): 20 (JSC::parseDate): 21 (JSC::msToSeconds): Deleted. 22 (JSC::msToWeekDay): Deleted. 23 1 24 2019-10-30 Peng Liu <peng.liu6@apple.com> 2 25 -
trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp
r251425 r251852 55 55 56 56 namespace JSC { 57 58 using namespace WTF;59 57 60 58 const ClassInfo DateConstructor::s_info = { "Function", &InternalFunction::s_info, &dateConstructorTable, nullptr, CREATE_METHOD_TABLE(DateConstructor) }; -
trunk/Source/JavaScriptCore/runtime/DateConversion.cpp
r251826 r251852 37 37 namespace JSC { 38 38 39 using namespace WTF;40 41 39 template<int width> 42 40 static inline void appendNumber(StringBuilder& builder, int value) … … 69 67 70 68 if (appendDate) { 71 builder.append( weekdayName[(t.weekDay() + 6) % 7]);69 builder.append(WTF::weekdayName[(t.weekDay() + 6) % 7]); 72 70 73 71 if (asUTCVariant) { … … 75 73 appendNumber<2>(builder, t.monthDay()); 76 74 builder.append(' '); 77 builder.append( monthName[t.month()]);75 builder.append(WTF::monthName[t.month()]); 78 76 } else { 79 77 builder.append(' '); 80 builder.append( monthName[t.month()]);78 builder.append(WTF::monthName[t.month()]); 81 79 builder.append(' '); 82 80 appendNumber<2>(builder, t.monthDay()); -
trunk/Source/JavaScriptCore/runtime/DateInstance.cpp
r251826 r251852 30 30 31 31 namespace JSC { 32 33 using namespace WTF;34 32 35 33 const ClassInfo DateInstance::s_info = {"Date", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(DateInstance)}; -
trunk/Source/JavaScriptCore/runtime/DatePrototype.cpp
r251826 r251852 69 69 70 70 namespace JSC { 71 72 using namespace WTF;73 71 74 72 EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDate(JSGlobalObject*, CallFrame*); -
trunk/Source/JavaScriptCore/runtime/JSDateMath.cpp
r251826 r251852 101 101 namespace JSC { 102 102 103 using namespace WTF;104 105 static inline double timeToMS(double hour, double min, double sec, double ms)106 {107 return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);108 }109 110 static inline int msToSeconds(double ms)111 {112 double result = fmod(floor(ms / msPerSecond), secondsPerMinute);113 if (result < 0)114 result += secondsPerMinute;115 return static_cast<int>(result);116 }117 118 // 0: Sunday, 1: Monday, etc.119 static inline int msToWeekDay(double ms)120 {121 int wd = (static_cast<int>(msToDays(ms)) + 4) % 7;122 if (wd < 0)123 wd += 7;124 return wd;125 }126 127 103 // Get the combined UTC + DST offset for the time passed in. 128 104 // … … 153 129 // and return the offset. 154 130 cache.end = newEnd; 155 cache.increment = msPerMonth;131 cache.increment = WTF::msPerMonth; 156 132 return endOffset; 157 133 } … … 164 140 cache.start = ms; 165 141 cache.end = newEnd; 166 cache.increment = msPerMonth;142 cache.increment = WTF::msPerMonth; 167 143 } else { 168 144 // The interval contains a DST offset change and the given time is … … 185 161 cache.start = ms; 186 162 cache.end = ms; 187 cache.increment = msPerMonth;163 cache.increment = WTF::msPerMonth; 188 164 return offset; 165 } 166 167 static inline double timeToMS(double hour, double min, double sec, double ms) 168 { 169 return (((hour * WTF::minutesPerHour + min) * WTF::secondsPerMinute + sec) * WTF::msPerSecond + ms); 189 170 } 190 171 … … 195 176 double localTimeResult = (day * WTF::msPerDay) + ms; 196 177 197 double localToUTCTimeOffset = inputTimeType == LocalTime178 double localToUTCTimeOffset = inputTimeType == WTF::LocalTime 198 179 ? localTimeOffset(vm, localTimeResult, inputTimeType).offset : 0; 199 180 … … 209 190 ms += localTime.offset; 210 191 } 211 212 const int year = msToYear(ms); 213 tm.setSecond(msToSeconds(ms)); 214 tm.setMinute(msToMinutes(ms)); 215 tm.setHour(msToHours(ms)); 216 tm.setWeekDay(msToWeekDay(ms)); 217 tm.setYearDay(dayInYear(ms, year)); 218 tm.setMonthDay(dayInMonthFromDayInYear(tm.yearDay(), isLeapYear(year))); 219 tm.setMonth(monthFromDayInYear(tm.yearDay(), isLeapYear(year))); 220 tm.setYear(year); 221 tm.setIsDST(localTime.isDST); 222 tm.setUTCOffsetInMinute(localTime.offset / WTF::msPerMinute); 192 tm = GregorianDateTime(ms, localTime); 223 193 } 224 194 … … 255 225 256 226 auto dateUtf8 = expectedString.value(); 257 double value = parseES5DateFromNullTerminatedCharacters(dateUtf8.data());227 double value = WTF::parseES5DateFromNullTerminatedCharacters(dateUtf8.data()); 258 228 if (std::isnan(value)) 259 229 value = parseDateFromNullTerminatedCharacters(vm, dateUtf8.data()); -
trunk/Source/WTF/ChangeLog
r251831 r251852 1 2019-10-31 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] DateMath should have TimeClipped version 4 https://bugs.webkit.org/show_bug.cgi?id=203550 5 6 Reviewed by Saam Barati. 7 8 We found that our Date constructor is slow because GregorianDateTime calculation takes so long. 9 We are doing many `fmod`, floating division, `floor` etc. These operations, in particular `fmod`, takes 10 very long time. As a result, 30% of JetStream2/date-format-xparb is taken by `fmod` function. 11 12 But since we are performance timeClip operation, double value in DateInstance is always Int52. We should 13 have integer version of GregorianDateTime calculation which avoids many unnecessary fmod etc. 14 15 While integer division is truncate-to-zero, many Date calculation requires `floor(value / xxx)`. For now, 16 we use integer fast path only when the value is Int52 and positive. 17 18 We see 10~ % improvement in JetStream2/date-format-xparb-SP (from 201 to 239). 19 20 * wtf/DateMath.cpp: 21 (WTF::isLeapYear): Deleted. 22 (WTF::daysInYear): Deleted. 23 (WTF::daysFrom1970ToYear): Deleted. 24 (WTF::msToDays): Deleted. 25 (WTF::msToYear): Deleted. 26 (WTF::dayInYear): Deleted. 27 (WTF::msToMinutes): Deleted. 28 (WTF::msToHours): Deleted. 29 (WTF::monthFromDayInYear): Deleted. 30 (WTF::checkMonth): Deleted. 31 (WTF::dayInMonthFromDayInYear): Deleted. 32 (WTF::dateToDaysFrom1970): Deleted. 33 (WTF::timeClip): Deleted. 34 * wtf/DateMath.h: 35 (WTF::TimeClippedPositiveMilliseconds::TimeClippedPositiveMilliseconds): 36 (WTF::TimeClippedPositiveMilliseconds::value const): 37 (WTF::TimeClippedPositiveMilliseconds::asDouble const): 38 (WTF::timeClip): 39 (WTF::daysFrom1970ToYear): 40 (WTF::daysFrom1970ToYearTimeClippedPositive): 41 (WTF::isLeapYear): 42 (WTF::daysInYear): 43 (WTF::msToDays): 44 (WTF::dayInYear): 45 (WTF::dateToDaysFrom1970): 46 (WTF::msToYear): 47 (WTF::msToMinutes): 48 (WTF::msToHours): 49 (WTF::msToSeconds): 50 (WTF::msToWeekDay): 51 (WTF::monthFromDayInYear): 52 (WTF::dayInMonthFromDayInYear): 53 * wtf/GregorianDateTime.cpp: 54 (WTF::GregorianDateTime::GregorianDateTime): 55 * wtf/GregorianDateTime.h: 56 1 57 2019-10-30 Alex Christensen <achristensen@webkit.org> 2 58 -
trunk/Source/WTF/wtf/DateMath.cpp
r250005 r251852 110 110 /* Constants */ 111 111 112 static constexpr double maxUnixTime = 2145859200.0; // 12/31/2037 113 // ECMAScript asks not to support for a date of which total 114 // millisecond value is larger than the following value. 115 // See 15.9.1.14 of ECMA-262 5th edition. 116 static constexpr double maxECMAScriptTime = 8.64E15; 112 const char* const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; 113 const char* const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 114 const char* const monthFullName[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; 117 115 118 116 // Day of year for the first day of each month, where index 0 is January, and day 0 is January 1. 119 117 // First for non-leap years, then for leap years. 120 staticconst int firstDayOfMonth[2][12] = {118 const int firstDayOfMonth[2][12] = { 121 119 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, 122 120 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} … … 134 132 #endif 135 133 136 bool isLeapYear(int year)137 {138 if (year % 4 != 0)139 return false;140 if (year % 400 == 0)141 return true;142 if (year % 100 == 0)143 return false;144 return true;145 }146 147 static inline int daysInYear(int year)148 {149 return 365 + isLeapYear(year);150 }151 152 static inline double daysFrom1970ToYear(int year)153 {154 // The Gregorian Calendar rules for leap years:155 // Every fourth year is a leap year. 2004, 2008, and 2012 are leap years.156 // However, every hundredth year is not a leap year. 1900 and 2100 are not leap years.157 // Every four hundred years, there's a leap year after all. 2000 and 2400 are leap years.158 159 static constexpr int leapDaysBefore1971By4Rule = 1970 / 4;160 static constexpr int excludedLeapDaysBefore1971By100Rule = 1970 / 100;161 static constexpr int leapDaysBefore1971By400Rule = 1970 / 400;162 163 const double yearMinusOne = year - 1;164 const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule;165 const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule;166 const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule;167 168 return 365.0 * (year - 1970.0) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule;169 }170 171 double msToDays(double ms)172 {173 return floor(ms / msPerDay);174 }175 176 134 static void appendTwoDigitNumber(StringBuilder& builder, int number) 177 135 { … … 182 140 } 183 141 184 int msToYear(double ms)185 {186 int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970);187 double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear);188 if (msFromApproxYearTo1970 > ms)189 return approxYear - 1;190 if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms)191 return approxYear + 1;192 return approxYear;193 }194 195 int dayInYear(double ms, int year)196 {197 return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year));198 }199 200 142 static inline double msToMilliseconds(double ms) 201 143 { … … 204 146 result += msPerDay; 205 147 return result; 206 }207 208 int msToMinutes(double ms)209 {210 double result = fmod(floor(ms / msPerMinute), minutesPerHour);211 if (result < 0)212 result += minutesPerHour;213 return static_cast<int>(result);214 }215 216 int msToHours(double ms)217 {218 double result = fmod(floor(ms/msPerHour), hoursPerDay);219 if (result < 0)220 result += hoursPerDay;221 return static_cast<int>(result);222 }223 224 int monthFromDayInYear(int dayInYear, bool leapYear)225 {226 const int d = dayInYear;227 int step;228 229 if (d < (step = 31))230 return 0;231 step += (leapYear ? 29 : 28);232 if (d < step)233 return 1;234 if (d < (step += 31))235 return 2;236 if (d < (step += 30))237 return 3;238 if (d < (step += 31))239 return 4;240 if (d < (step += 30))241 return 5;242 if (d < (step += 31))243 return 6;244 if (d < (step += 31))245 return 7;246 if (d < (step += 30))247 return 8;248 if (d < (step += 31))249 return 9;250 if (d < (step += 30))251 return 10;252 return 11;253 }254 255 static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& startDayOfNextMonth, int daysInThisMonth)256 {257 startDayOfThisMonth = startDayOfNextMonth;258 startDayOfNextMonth += daysInThisMonth;259 return (dayInYear <= startDayOfNextMonth);260 }261 262 int dayInMonthFromDayInYear(int dayInYear, bool leapYear)263 {264 const int d = dayInYear;265 int step;266 int next = 30;267 268 if (d <= next)269 return d + 1;270 const int daysInFeb = (leapYear ? 29 : 28);271 if (checkMonth(d, step, next, daysInFeb))272 return d - step;273 if (checkMonth(d, step, next, 31))274 return d - step;275 if (checkMonth(d, step, next, 30))276 return d - step;277 if (checkMonth(d, step, next, 31))278 return d - step;279 if (checkMonth(d, step, next, 30))280 return d - step;281 if (checkMonth(d, step, next, 31))282 return d - step;283 if (checkMonth(d, step, next, 31))284 return d - step;285 if (checkMonth(d, step, next, 30))286 return d - step;287 if (checkMonth(d, step, next, 31))288 return d - step;289 if (checkMonth(d, step, next, 30))290 return d - step;291 step = next;292 return d - step;293 }294 295 int dayInYear(int year, int month, int day)296 {297 return firstDayOfMonth[isLeapYear(year)][month] + day - 1;298 }299 300 double dateToDaysFrom1970(int year, int month, int day)301 {302 year += month / 12;303 304 month %= 12;305 if (month < 0) {306 month += 12;307 --year;308 }309 310 double yearday = floor(daysFrom1970ToYear(year));311 ASSERT((year >= 1970 && yearday >= 0) || (year < 1970 && yearday < 0));312 return yearday + dayInYear(year, month, day);313 148 } 314 149 … … 1160 995 } 1161 996 1162 double timeClip(double t)1163 {1164 if (std::abs(t) > maxECMAScriptTime)1165 return std::numeric_limits<double>::quiet_NaN();1166 return std::trunc(t) + 0.0;1167 }1168 1169 997 // See http://tools.ietf.org/html/rfc2822#section-3.3 for more information. 1170 998 String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, unsigned year, unsigned hours, unsigned minutes, unsigned seconds, int utcOffset) -
trunk/Source/WTF/wtf/DateMath.h
r251826 r251852 93 93 WTF_EXPORT_PRIVATE double parseDateFromNullTerminatedCharacters(const char* dateString); 94 94 WTF_EXPORT_PRIVATE double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset); 95 WTF_EXPORT_PRIVATE double timeClip(double);96 95 // dayOfWeek: [0, 6] 0 being Monday, day: [1, 31], month: [0, 11], year: ex: 2011, hours: [0, 23], minutes: [0, 59], seconds: [0, 59], utcOffset: [-720,720]. 97 96 String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, unsigned year, unsigned hours, unsigned minutes, unsigned seconds, int utcOffset); … … 103 102 } 104 103 105 const char* const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; 106 const char* const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 107 const char* const monthFullName[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; 104 extern WTF_EXPORT_PRIVATE const char* const weekdayName[7]; 105 extern WTF_EXPORT_PRIVATE const char* const monthName[12]; 106 extern WTF_EXPORT_PRIVATE const char* const monthFullName[12]; 107 extern WTF_EXPORT_PRIVATE const int firstDayOfMonth[2][12]; 108 108 109 109 static constexpr double hoursPerDay = 24.0; … … 118 118 static constexpr double msPerDay = msPerSecond * secondsPerDay; 119 119 120 WTF_EXPORT_PRIVATE bool isLeapYear(int year); 120 static constexpr double maxUnixTime = 2145859200.0; // 12/31/2037 121 // ECMAScript asks not to support for a date of which total 122 // millisecond value is larger than the following value. 123 // See 15.9.1.14 of ECMA-262 5th edition. 124 static constexpr double maxECMAScriptTime = 8.64E15; 125 126 class TimeClippedPositiveMilliseconds { 127 public: 128 static constexpr int64_t hoursPerDay = 24; 129 static constexpr int64_t minutesPerHour = 60; 130 static constexpr int64_t secondsPerMinute = 60; 131 static constexpr int64_t msPerSecond = 1000; 132 static constexpr int64_t msPerMonth = 2592000000; 133 static constexpr int64_t secondsPerHour = secondsPerMinute * minutesPerHour; 134 static constexpr int64_t secondsPerDay = secondsPerHour * hoursPerDay; 135 static constexpr int64_t msPerMinute = msPerSecond * secondsPerMinute; 136 static constexpr int64_t msPerHour = msPerSecond * secondsPerHour; 137 static constexpr int64_t msPerDay = msPerSecond * secondsPerDay; 138 static constexpr int64_t maxECMAScriptTime = 8.64E15; 139 140 explicit TimeClippedPositiveMilliseconds(int64_t value) 141 : m_value(value) 142 { 143 ASSERT(value >= 0); 144 } 145 146 int64_t value() const { return m_value; } 147 double asDouble() const { return static_cast<double>(m_value); } 148 private: 149 int64_t m_value; 150 }; 151 152 inline double timeClip(double t) 153 { 154 if (std::abs(t) > maxECMAScriptTime) 155 return std::numeric_limits<double>::quiet_NaN(); 156 return std::trunc(t) + 0.0; 157 } 158 159 inline double daysFrom1970ToYear(int year) 160 { 161 // The Gregorian Calendar rules for leap years: 162 // Every fourth year is a leap year. 2004, 2008, and 2012 are leap years. 163 // However, every hundredth year is not a leap year. 1900 and 2100 are not leap years. 164 // Every four hundred years, there's a leap year after all. 2000 and 2400 are leap years. 165 166 static constexpr int leapDaysBefore1971By4Rule = 1970 / 4; 167 static constexpr int excludedLeapDaysBefore1971By100Rule = 1970 / 100; 168 static constexpr int leapDaysBefore1971By400Rule = 1970 / 400; 169 170 const double yearMinusOne = year - 1; 171 const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule; 172 const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule; 173 const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule; 174 175 return 365.0 * (year - 1970.0) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule; 176 } 177 178 inline int64_t daysFrom1970ToYearTimeClippedPositive(int year) 179 { 180 static constexpr int leapDaysBefore1971By4Rule = 1970 / 4; 181 static constexpr int excludedLeapDaysBefore1971By100Rule = 1970 / 100; 182 static constexpr int leapDaysBefore1971By400Rule = 1970 / 400; 183 184 ASSERT(year >= 1970); 185 const int64_t yearMinusOne = year - 1; 186 const int64_t yearsToAddBy4Rule = yearMinusOne / 4.0 - leapDaysBefore1971By4Rule; 187 const int64_t yearsToExcludeBy100Rule = yearMinusOne / 100.0 - excludedLeapDaysBefore1971By100Rule; 188 const int64_t yearsToAddBy400Rule = yearMinusOne / 400.0 - leapDaysBefore1971By400Rule; 189 190 return 365 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule; 191 } 192 193 inline bool isLeapYear(int year) 194 { 195 if (year % 4 != 0) 196 return false; 197 if (year % 400 == 0) 198 return true; 199 if (year % 100 == 0) 200 return false; 201 return true; 202 } 203 204 inline int daysInYear(int year) 205 { 206 return 365 + isLeapYear(year); 207 } 208 209 inline double msToDays(double ms) 210 { 211 return floor(ms / msPerDay); 212 } 213 214 inline int64_t msToDays(TimeClippedPositiveMilliseconds ms) 215 { 216 return ms.value() / TimeClippedPositiveMilliseconds::msPerDay; 217 } 218 219 inline int dayInYear(int year, int month, int day) 220 { 221 return firstDayOfMonth[isLeapYear(year)][month] + day - 1; 222 } 223 224 inline int dayInYear(double ms, int year) 225 { 226 return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year)); 227 } 228 229 inline int dayInYear(TimeClippedPositiveMilliseconds ms, int year) 230 { 231 return static_cast<int>(msToDays(ms) - daysFrom1970ToYearTimeClippedPositive(year)); 232 } 121 233 122 234 // Returns the number of days from 1970-01-01 to the specified date. 123 WTF_EXPORT_PRIVATE double dateToDaysFrom1970(int year, int month, int day); 124 WTF_EXPORT_PRIVATE int msToYear(double ms); 125 WTF_EXPORT_PRIVATE double msToDays(double ms); 126 WTF_EXPORT_PRIVATE int msToMinutes(double ms); 127 WTF_EXPORT_PRIVATE int msToHours(double ms); 128 WTF_EXPORT_PRIVATE int dayInYear(int year, int month, int day); 129 WTF_EXPORT_PRIVATE int dayInYear(double ms, int year); 130 WTF_EXPORT_PRIVATE int monthFromDayInYear(int dayInYear, bool leapYear); 131 WTF_EXPORT_PRIVATE int dayInMonthFromDayInYear(int dayInYear, bool leapYear); 235 inline double dateToDaysFrom1970(int year, int month, int day) 236 { 237 year += month / 12; 238 239 month %= 12; 240 if (month < 0) { 241 month += 12; 242 --year; 243 } 244 245 double yearday = floor(daysFrom1970ToYear(year)); 246 ASSERT((year >= 1970 && yearday >= 0) || (year < 1970 && yearday < 0)); 247 return yearday + dayInYear(year, month, day); 248 } 249 250 inline int msToYear(double ms) 251 { 252 int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970); 253 double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear); 254 if (msFromApproxYearTo1970 > ms) 255 return approxYear - 1; 256 if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms) 257 return approxYear + 1; 258 return approxYear; 259 } 260 261 inline int msToMinutes(double ms) 262 { 263 double result = fmod(floor(ms / msPerMinute), minutesPerHour); 264 if (result < 0) 265 result += minutesPerHour; 266 return static_cast<int>(result); 267 } 268 269 inline int msToMinutes(TimeClippedPositiveMilliseconds ms) 270 { 271 int64_t result = (ms.value() / TimeClippedPositiveMilliseconds::msPerMinute) % TimeClippedPositiveMilliseconds::minutesPerHour; 272 ASSERT(result >= 0); 273 return static_cast<int>(result); 274 } 275 276 inline int msToHours(double ms) 277 { 278 double result = fmod(floor(ms / msPerHour), hoursPerDay); 279 if (result < 0) 280 result += hoursPerDay; 281 return static_cast<int>(result); 282 } 283 284 inline int msToHours(TimeClippedPositiveMilliseconds ms) 285 { 286 int64_t result = (ms.value() / TimeClippedPositiveMilliseconds::msPerHour) % TimeClippedPositiveMilliseconds::hoursPerDay; 287 ASSERT(result >= 0); 288 return static_cast<int>(result); 289 } 290 291 inline int msToSeconds(double ms) 292 { 293 double result = fmod(floor(ms / msPerSecond), secondsPerMinute); 294 if (result < 0) 295 result += secondsPerMinute; 296 return static_cast<int>(result); 297 } 298 299 inline int msToSeconds(TimeClippedPositiveMilliseconds ms) 300 { 301 int64_t result = ms.value() / TimeClippedPositiveMilliseconds::msPerSecond % TimeClippedPositiveMilliseconds::secondsPerMinute; 302 ASSERT(result >= 0); 303 return static_cast<int>(result); 304 } 305 306 // 0: Sunday, 1: Monday, etc. 307 inline int msToWeekDay(double ms) 308 { 309 int wd = (static_cast<int>(msToDays(ms)) + 4) % 7; 310 if (wd < 0) 311 wd += 7; 312 return wd; 313 } 314 315 inline int msToWeekDay(TimeClippedPositiveMilliseconds ms) 316 { 317 int result = (static_cast<int>(msToDays(ms)) + 4) % 7; 318 ASSERT(result >= 0); 319 return result; 320 } 321 322 inline int monthFromDayInYear(int dayInYear, bool leapYear) 323 { 324 const int d = dayInYear; 325 int step; 326 327 if (d < (step = 31)) 328 return 0; 329 step += (leapYear ? 29 : 28); 330 if (d < step) 331 return 1; 332 if (d < (step += 31)) 333 return 2; 334 if (d < (step += 30)) 335 return 3; 336 if (d < (step += 31)) 337 return 4; 338 if (d < (step += 30)) 339 return 5; 340 if (d < (step += 31)) 341 return 6; 342 if (d < (step += 31)) 343 return 7; 344 if (d < (step += 30)) 345 return 8; 346 if (d < (step += 31)) 347 return 9; 348 if (d < (step += 30)) 349 return 10; 350 return 11; 351 } 352 353 inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear) 354 { 355 auto checkMonth = [] (int dayInYear, int& startDayOfThisMonth, int& startDayOfNextMonth, int daysInThisMonth) -> bool { 356 startDayOfThisMonth = startDayOfNextMonth; 357 startDayOfNextMonth += daysInThisMonth; 358 return (dayInYear <= startDayOfNextMonth); 359 }; 360 361 const int d = dayInYear; 362 int step; 363 int next = 30; 364 365 if (d <= next) 366 return d + 1; 367 const int daysInFeb = (leapYear ? 29 : 28); 368 if (checkMonth(d, step, next, daysInFeb)) 369 return d - step; 370 if (checkMonth(d, step, next, 31)) 371 return d - step; 372 if (checkMonth(d, step, next, 30)) 373 return d - step; 374 if (checkMonth(d, step, next, 31)) 375 return d - step; 376 if (checkMonth(d, step, next, 30)) 377 return d - step; 378 if (checkMonth(d, step, next, 31)) 379 return d - step; 380 if (checkMonth(d, step, next, 31)) 381 return d - step; 382 if (checkMonth(d, step, next, 30)) 383 return d - step; 384 if (checkMonth(d, step, next, 31)) 385 return d - step; 386 if (checkMonth(d, step, next, 30)) 387 return d - step; 388 step = next; 389 return d - step; 390 } 132 391 133 392 // Returns combined offset in millisecond (UTC + DST). … … 156 415 using WTF::LocalTimeOffset; 157 416 using WTF::calculateLocalTimeOffset; 417 using WTF::timeClip; 418 using WTF::jsCurrentTime; -
trunk/Source/WTF/wtf/GregorianDateTime.cpp
r251826 r251852 35 35 36 36 namespace WTF { 37 38 GregorianDateTime::GregorianDateTime(double ms, LocalTimeOffset localTime) 39 { 40 if (ms >= 0 41 #if OS(WINDOWS) && CPU(X86) 42 // The VS Compiler for 32-bit builds generates a floating point error when attempting to cast 43 // from an infinity to a 64-bit integer. We leave this routine with the floating point error 44 // left in a register, causing undefined behavior in later floating point operations. 45 // 46 // To avoid this issue, we check for infinity here, and return false in that case. 47 && !std::isinf(ms) 48 #endif 49 ) { 50 int64_t integer = static_cast<int64_t>(ms); 51 if (static_cast<double>(integer) == ms && integer <= maxECMAScriptTime) { 52 // Positive integer fast path. 53 WTF::TimeClippedPositiveMilliseconds timeClipped(integer); 54 const int year = msToYear(ms); 55 setSecond(msToSeconds(timeClipped)); 56 setMinute(msToMinutes(timeClipped)); 57 setHour(msToHours(timeClipped)); 58 setWeekDay(msToWeekDay(timeClipped)); 59 int yearDay = dayInYear(timeClipped, year); 60 bool leapYear = isLeapYear(year); 61 setYearDay(yearDay); 62 setMonthDay(dayInMonthFromDayInYear(yearDay, leapYear)); 63 setMonth(monthFromDayInYear(yearDay, leapYear)); 64 setYear(year); 65 setIsDST(localTime.isDST); 66 setUTCOffsetInMinute(localTime.offset / WTF::msPerMinute); 67 return; 68 } 69 } 70 const int year = msToYear(ms); 71 setSecond(msToSeconds(ms)); 72 setMinute(msToMinutes(ms)); 73 setHour(msToHours(ms)); 74 setWeekDay(msToWeekDay(ms)); 75 int yearDay = dayInYear(ms, year); 76 bool leapYear = isLeapYear(year); 77 setYearDay(yearDay); 78 setMonthDay(dayInMonthFromDayInYear(yearDay, leapYear)); 79 setMonth(monthFromDayInYear(yearDay, leapYear)); 80 setYear(year); 81 setIsDST(localTime.isDST); 82 setUTCOffsetInMinute(localTime.offset / WTF::msPerMinute); 83 } 37 84 38 85 void GregorianDateTime::setToCurrentLocalTime() -
trunk/Source/WTF/wtf/GregorianDateTime.h
r251826 r251852 37 37 public: 38 38 GregorianDateTime() = default; 39 WTF_EXPORT_PRIVATE explicit GregorianDateTime(double ms, LocalTimeOffset); 39 40 40 41 inline int year() const { return m_year; }
Note: See TracChangeset
for help on using the changeset viewer.