fa0fb42e07ef436a5cc08006e6dd32db70c3ec47
[WebKit-https.git] / Source / JavaScriptCore / runtime / DateConversion.cpp
1 /*
2  * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26 #include "DateConversion.h"
27
28 #include <wtf/Assertions.h>
29 #include <wtf/DateMath.h>
30 #include <wtf/text/StringBuilder.h>
31 #include <wtf/text/WTFString.h>
32
33 #if OS(WINDOWS)
34 #include <windows.h>
35 #include <wtf/text/win/WCharStringExtras.h>
36 #endif
37
38 namespace JSC {
39
40 using namespace WTF;
41
42 template<int width>
43 static inline void appendNumber(StringBuilder& builder, int value)
44 {
45     int fillingZerosCount = width;
46     if (value < 0) {
47         builder.append('-');
48         value = -value;
49         --fillingZerosCount;
50     }
51     String valueString = String::number(value);
52     fillingZerosCount -= valueString.length();
53     for (int i = 0; i < fillingZerosCount; ++i)
54         builder.append('0');
55     builder.append(valueString);
56 }
57
58 template<>
59 void appendNumber<2>(StringBuilder& builder, int value)
60 {
61     ASSERT(0 <= value && value <= 99);
62     builder.append(static_cast<char>('0' + value / 10));
63     builder.append(static_cast<char>('0' + value % 10));
64 }
65
66 String formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool asUTCVariant)
67 {
68     bool appendDate = format & DateTimeFormatDate;
69     bool appendTime = format & DateTimeFormatTime;
70
71     StringBuilder builder;
72
73     if (appendDate) {
74         builder.append(weekdayName[(t.weekDay() + 6) % 7]);
75
76         if (asUTCVariant) {
77             builder.appendLiteral(", ");
78             appendNumber<2>(builder, t.monthDay());
79             builder.append(' ');
80             builder.append(monthName[t.month()]);
81         } else {
82             builder.append(' ');
83             builder.append(monthName[t.month()]);
84             builder.append(' ');
85             appendNumber<2>(builder, t.monthDay());
86         }
87         builder.append(' ');
88         appendNumber<4>(builder, t.year());
89     }
90
91     if (appendDate && appendTime)
92         builder.append(' ');
93
94     if (appendTime) {
95         appendNumber<2>(builder, t.hour());
96         builder.append(':');
97         appendNumber<2>(builder, t.minute());
98         builder.append(':');
99         appendNumber<2>(builder, t.second());
100         builder.appendLiteral(" GMT");
101
102         if (!asUTCVariant) {
103             int offset = abs(t.utcOffset()) / 60;
104             builder.append(t.utcOffset() < 0 ? '-' : '+');
105             appendNumber<2>(builder, offset / 60);
106             appendNumber<2>(builder, offset % 60);
107
108 #if OS(WINDOWS)
109             TIME_ZONE_INFORMATION timeZoneInformation;
110             GetTimeZoneInformation(&timeZoneInformation);
111             const WCHAR* winTimeZoneName = t.isDST() ? timeZoneInformation.DaylightName : timeZoneInformation.StandardName;
112             String timeZoneName = nullTerminatedWCharToString(winTimeZoneName);
113 #else
114             struct tm gtm = t;
115             char timeZoneName[70];
116             strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
117 #endif
118             if (timeZoneName[0]) {
119                 builder.appendLiteral(" (");
120                 builder.append(timeZoneName);
121                 builder.append(')');
122             }
123         }
124     }
125
126     return builder.toString().impl();
127 }
128
129 } // namespace JSC