]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/DateConversion.cpp
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / runtime / DateConversion.cpp
index 1418876ed1492c1dce52ad9d7a80936a6ca8bc1e..0b57f012d5614c0247a07b43400de975bd88f842 100644 (file)
 /*
- * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com>
  *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
  *
- * 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.
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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 "DateConversion.h"
 
-#include "CallFrame.h"
-#include "JSObject.h"
-#include "ScopeChain.h"
-#include "UString.h"
+#include <wtf/Assertions.h>
 #include <wtf/DateMath.h>
-#include <wtf/StringExtras.h>
-#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/WTFString.h>
+
+#if OS(WINDOWS)
+#include <windows.h>
+#endif
 
 using namespace WTF;
 
 namespace JSC {
 
-double parseDate(ExecState* exec, const UString &date)
+template<int width>
+static inline void appendNumber(StringBuilder& builder, int value)
 {
-    if (date == exec->globalData().cachedDateString)
-        return exec->globalData().cachedDateStringValue;
-    double value = parseES5DateFromNullTerminatedCharacters(date.utf8().data());
-    if (isnan(value))
-        value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data());
-    exec->globalData().cachedDateString = date;
-    exec->globalData().cachedDateStringValue = value;
-    return value;
+    int fillingZerosCount = width;
+    if (value < 0) {
+        builder.append('-');
+        value = -value;
+        --fillingZerosCount;
+    }
+    String valueString = String::number(value);
+    fillingZerosCount -= valueString.length();
+    for (int i = 0; i < fillingZerosCount; ++i)
+        builder.append('0');
+    builder.append(valueString);
 }
 
-void formatDate(const GregorianDateTime &t, DateConversionBuffer& buffer)
+template<>
+void appendNumber<2>(StringBuilder& builder, int value)
 {
-    snprintf(buffer, DateConversionBufferSize, "%s %s %02d %04d",
-        weekdayName[(t.weekDay + 6) % 7],
-        monthName[t.month], t.monthDay, t.year + 1900);
+    ASSERT(0 <= value && value <= 99);
+    builder.append(static_cast<char>('0' + value / 10));
+    builder.append(static_cast<char>('0' + value % 10));
 }
 
-void formatDateUTCVariant(const GregorianDateTime &t, DateConversionBuffer& buffer)
+String formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool asUTCVariant)
 {
-    snprintf(buffer, DateConversionBufferSize, "%s, %02d %s %04d",
-        weekdayName[(t.weekDay + 6) % 7],
-        t.monthDay, monthName[t.month], t.year + 1900);
-}
+    bool appendDate = format & DateTimeFormatDate;
+    bool appendTime = format & DateTimeFormatTime;
 
-void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer)
-{
-    int offset = abs(gmtoffset(t));
-    char timeZoneName[70];
-    struct tm gtm = t;
-    strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
-
-    if (timeZoneName[0]) {
-        snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)",
-            t.hour, t.minute, t.second,
-            gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
-    } else {
-        snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d",
-            t.hour, t.minute, t.second,
-            gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
+    StringBuilder builder;
+
+    if (appendDate) {
+        builder.append(weekdayName[(t.weekDay() + 6) % 7]);
+
+        if (asUTCVariant) {
+            builder.appendLiteral(", ");
+            appendNumber<2>(builder, t.monthDay());
+            builder.append(' ');
+            builder.append(monthName[t.month()]);
+        } else {
+            builder.append(' ');
+            builder.append(monthName[t.month()]);
+            builder.append(' ');
+            appendNumber<2>(builder, t.monthDay());
+        }
+        builder.append(' ');
+        appendNumber<4>(builder, t.year());
     }
-}
 
-void formatTimeUTC(const GregorianDateTime &t, DateConversionBuffer& buffer)
-{
-    snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
+    if (appendDate && appendTime)
+        builder.append(' ');
+
+    if (appendTime) {
+        appendNumber<2>(builder, t.hour());
+        builder.append(':');
+        appendNumber<2>(builder, t.minute());
+        builder.append(':');
+        appendNumber<2>(builder, t.second());
+        builder.appendLiteral(" GMT");
+
+        if (!asUTCVariant) {
+            int offset = abs(t.utcOffset()) / 60;
+            builder.append(t.utcOffset() < 0 ? '-' : '+');
+            appendNumber<2>(builder, offset / 60);
+            appendNumber<2>(builder, offset % 60);
+
+#if OS(WINDOWS)
+            TIME_ZONE_INFORMATION timeZoneInformation;
+            GetTimeZoneInformation(&timeZoneInformation);
+            const WCHAR* timeZoneName = t.isDST() ? timeZoneInformation.DaylightName : timeZoneInformation.StandardName;
+#else
+            struct tm gtm = t;
+            char timeZoneName[70];
+            strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
+#endif
+            if (timeZoneName[0]) {
+                builder.appendLiteral(" (");
+                builder.append(timeZoneName);
+                builder.append(')');
+            }
+        }
+    }
+
+    return builder.toString().impl();
 }
 
 } // namespace JSC