summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSDateMath.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-10-15 09:45:50 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-10-15 09:45:50 +0000
commite15dd966d523731101f70ccf768bba12435a0208 (patch)
treeae9cb828a24ded2585a41af3f21411523b47897d /Source/JavaScriptCore/runtime/JSDateMath.cpp
downloadWebKitGtk-tarball-e15dd966d523731101f70ccf768bba12435a0208.tar.gz
webkitgtk-2.10.2webkitgtk-2.10.2
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSDateMath.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/JSDateMath.cpp253
1 files changed, 253 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp
new file mode 100644
index 000000000..1482e312f
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/JSDateMath.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ * Copyright (C) 2010 &yet, LLC. (nate@andyet.net)
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+
+ * Copyright 2006-2008 the V8 project authors. All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSDateMath.h"
+
+#include "JSObject.h"
+#include "JSScope.h"
+#include "JSCInlines.h"
+
+#include <algorithm>
+#include <limits.h>
+#include <limits>
+#include <stdint.h>
+#include <time.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/Assertions.h>
+#include <wtf/CurrentTime.h>
+#include <wtf/MathExtras.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/StringExtras.h>
+#include <wtf/text/StringBuilder.h>
+
+#if HAVE(ERRNO_H)
+#include <errno.h>
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if HAVE(SYS_TIMEB_H)
+#include <sys/timeb.h>
+#endif
+
+using namespace WTF;
+
+namespace JSC {
+
+static inline double timeToMS(double hour, double min, double sec, double ms)
+{
+ return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
+}
+
+static inline int msToSeconds(double ms)
+{
+ double result = fmod(floor(ms / msPerSecond), secondsPerMinute);
+ if (result < 0)
+ result += secondsPerMinute;
+ return static_cast<int>(result);
+}
+
+// 0: Sunday, 1: Monday, etc.
+static inline int msToWeekDay(double ms)
+{
+ int wd = (static_cast<int>(msToDays(ms)) + 4) % 7;
+ if (wd < 0)
+ wd += 7;
+ return wd;
+}
+
+// Get the combined UTC + DST offset for the time passed in.
+//
+// NOTE: The implementation relies on the fact that no time zones have
+// more than one daylight savings offset change per month.
+// If this function is called with NaN it returns NaN.
+static LocalTimeOffset localTimeOffset(VM& vm, double ms, WTF::TimeType inputTimeType = WTF::UTCTime)
+{
+ LocalTimeOffsetCache& cache = vm.localTimeOffsetCache;
+ double start = cache.start;
+ double end = cache.end;
+ WTF::TimeType cachedTimeType = cache.timeType;
+
+ if (cachedTimeType == inputTimeType && start <= ms) {
+ // If the time fits in the cached interval, return the cached offset.
+ if (ms <= end) return cache.offset;
+
+ // Compute a possible new interval end.
+ double newEnd = end + cache.increment;
+
+ if (ms <= newEnd) {
+ LocalTimeOffset endOffset = calculateLocalTimeOffset(newEnd, inputTimeType);
+ if (cache.offset == endOffset) {
+ // If the offset at the end of the new interval still matches
+ // the offset in the cache, we grow the cached time interval
+ // and return the offset.
+ cache.end = newEnd;
+ cache.increment = msPerMonth;
+ return endOffset;
+ }
+ LocalTimeOffset offset = calculateLocalTimeOffset(ms, inputTimeType);
+ if (offset == endOffset) {
+ // The offset at the given time is equal to the offset at the
+ // new end of the interval, so that means that we've just skipped
+ // the point in time where the DST offset change occurred. Updated
+ // the interval to reflect this and reset the increment.
+ cache.start = ms;
+ cache.end = newEnd;
+ cache.increment = msPerMonth;
+ } else {
+ // The interval contains a DST offset change and the given time is
+ // before it. Adjust the increment to avoid a linear search for
+ // the offset change point and change the end of the interval.
+ cache.increment /= 3;
+ cache.end = ms;
+ }
+ // Update the offset in the cache and return it.
+ cache.offset = offset;
+ return offset;
+ }
+ }
+
+ // Compute the DST offset for the time and shrink the cache interval
+ // to only contain the time. This allows fast repeated DST offset
+ // computations for the same time.
+ LocalTimeOffset offset = calculateLocalTimeOffset(ms, inputTimeType);
+ cache.offset = offset;
+ cache.start = ms;
+ cache.end = ms;
+ cache.increment = msPerMonth;
+ cache.timeType = inputTimeType;
+ return offset;
+}
+
+double gregorianDateTimeToMS(VM& vm, const GregorianDateTime& t, double milliSeconds, WTF::TimeType inputTimeType)
+{
+ double day = dateToDaysFrom1970(t.year(), t.month(), t.monthDay());
+ double ms = timeToMS(t.hour(), t.minute(), t.second(), milliSeconds);
+ double localTimeResult = (day * WTF::msPerDay) + ms;
+ double localToUTCTimeOffset = inputTimeType == LocalTime
+ ? localTimeOffset(vm, localTimeResult, inputTimeType).offset : 0;
+
+ return localTimeResult - localToUTCTimeOffset;
+}
+
+// input is UTC
+void msToGregorianDateTime(VM& vm, double ms, WTF::TimeType outputTimeType, GregorianDateTime& tm)
+{
+ LocalTimeOffset localTime;
+ if (outputTimeType == WTF::LocalTime) {
+ localTime = localTimeOffset(vm, ms);
+ ms += localTime.offset;
+ }
+
+ const int year = msToYear(ms);
+ tm.setSecond(msToSeconds(ms));
+ tm.setMinute(msToMinutes(ms));
+ tm.setHour(msToHours(ms));
+ tm.setWeekDay(msToWeekDay(ms));
+ tm.setYearDay(dayInYear(ms, year));
+ tm.setMonthDay(dayInMonthFromDayInYear(tm.yearDay(), isLeapYear(year)));
+ tm.setMonth(monthFromDayInYear(tm.yearDay(), isLeapYear(year)));
+ tm.setYear(year);
+ tm.setIsDST(localTime.isDST);
+ tm.setUtcOffset(localTime.offset / WTF::msPerSecond);
+}
+
+double parseDateFromNullTerminatedCharacters(VM& vm, const char* dateString)
+{
+ bool haveTZ;
+ int offset;
+ double localTimeMS = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset);
+ if (std::isnan(localTimeMS))
+ return std::numeric_limits<double>::quiet_NaN();
+
+ // fall back to local timezone.
+ if (!haveTZ)
+ offset = localTimeOffset(vm, localTimeMS, WTF::LocalTime).offset / WTF::msPerMinute;
+
+ return localTimeMS - (offset * WTF::msPerMinute);
+}
+
+double parseDate(VM& vm, const String& date)
+{
+ if (date == vm.cachedDateString)
+ return vm.cachedDateStringValue;
+ double value = parseES5DateFromNullTerminatedCharacters(date.utf8().data());
+ if (std::isnan(value))
+ value = parseDateFromNullTerminatedCharacters(vm, date.utf8().data());
+ vm.cachedDateString = date;
+ vm.cachedDateStringValue = value;
+ return value;
+}
+
+} // namespace JSC