1/*
2 * Copyright (C) 2012 Patrick Gansterer <[email protected]>
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#endif
36
37namespace JSC {
38
39template<int width>
40static inline void appendNumber(StringBuilder& builder, int value)
41{
42 if (value < 0) {
43 builder.append('-');
44 value = -value;
45 }
46 String valueString = String::number(value);
47 int fillingZerosCount = width - valueString.length();
48 for (int i = 0; i < fillingZerosCount; ++i)
49 builder.append('0');
50 builder.append(valueString);
51}
52
53template<>
54void appendNumber<2>(StringBuilder& builder, int value)
55{
56 ASSERT(0 <= value && value <= 99);
57 builder.append(static_cast<char>('0' + value / 10));
58 builder.append(static_cast<char>('0' + value % 10));
59}
60
61String formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool asUTCVariant)
62{
63 bool appendDate = format & DateTimeFormatDate;
64 bool appendTime = format & DateTimeFormatTime;
65
66 StringBuilder builder;
67
68 if (appendDate) {
69 builder.append(WTF::weekdayName[(t.weekDay() + 6) % 7]);
70
71 if (asUTCVariant) {
72 builder.appendLiteral(", ");
73 appendNumber<2>(builder, t.monthDay());
74 builder.append(' ');
75 builder.append(WTF::monthName[t.month()]);
76 } else {
77 builder.append(' ');
78 builder.append(WTF::monthName[t.month()]);
79 builder.append(' ');
80 appendNumber<2>(builder, t.monthDay());
81 }
82 builder.append(' ');
83 appendNumber<4>(builder, t.year());
84 }
85
86 if (appendDate && appendTime)
87 builder.append(' ');
88
89 if (appendTime) {
90 appendNumber<2>(builder, t.hour());
91 builder.append(':');
92 appendNumber<2>(builder, t.minute());
93 builder.append(':');
94 appendNumber<2>(builder, t.second());
95 builder.appendLiteral(" GMT");
96
97 if (!asUTCVariant) {
98 int offset = abs(t.utcOffsetInMinute());
99 builder.append(t.utcOffsetInMinute() < 0 ? '-' : '+');
100 appendNumber<2>(builder, offset / 60);
101 appendNumber<2>(builder, offset % 60);
102
103#if OS(WINDOWS)
104 TIME_ZONE_INFORMATION timeZoneInformation;
105 GetTimeZoneInformation(&timeZoneInformation);
106 const WCHAR* winTimeZoneName = t.isDST() ? timeZoneInformation.DaylightName : timeZoneInformation.StandardName;
107 String timeZoneName(winTimeZoneName);
108#else
109 struct tm gtm = t;
110 char timeZoneName[70];
111 strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
112#endif
113 if (timeZoneName[0]) {
114 builder.appendLiteral(" (");
115 builder.append(timeZoneName);
116 builder.append(')');
117 }
118 }
119 }
120
121 return builder.toString().impl();
122}
123
124} // namespace JSC
125