/ runtime / DateConversion.cpp
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  #endif
 36  
 37  namespace JSC {
 38  
 39  template<int width>
 40  static 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  
 53  template<>
 54  void 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  
 61  String 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