intl/locale/src/windows/nsDateTimeFormatWin.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsDateTimeFormatWin.h"
     7 #include "nsIServiceManager.h"
     8 #include "nsIComponentManager.h"
     9 #include "nsILocaleService.h"
    10 #include "nsWin32Locale.h"
    11 #include "nsUnicharUtils.h"
    12 #include "nsCRT.h"
    13 #include "nsCOMPtr.h"
    16 #define NSDATETIMEFORMAT_BUFFER_LEN  80
    18 NS_IMPL_ISUPPORTS(nsDateTimeFormatWin, nsIDateTimeFormat)
    21 // init this interface to a specified locale
    22 nsresult nsDateTimeFormatWin::Initialize(nsILocale* locale)
    23 {
    24   nsAutoString localeStr;
    25   nsresult res = NS_OK;
    27   // use cached info if match with stored locale
    28   if (!locale) {
    29     if (!mLocale.IsEmpty() && 
    30         mLocale.Equals(mAppLocale, nsCaseInsensitiveStringComparator())) {
    31       return NS_OK;
    32     }
    33   }
    34   else {
    35     res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), localeStr);
    36     if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
    37       if (!mLocale.IsEmpty() && 
    38           mLocale.Equals(localeStr, nsCaseInsensitiveStringComparator())) {
    39         return NS_OK;
    40       }
    41     }
    42   }
    44   // default LCID (en-US)
    45   mLCID = 1033;
    47   // get locale string, use app default if no locale specified
    48   if (!locale) {
    49     nsCOMPtr<nsILocaleService> localeService = 
    50              do_GetService(NS_LOCALESERVICE_CONTRACTID);
    51     if (localeService) {
    52       nsCOMPtr<nsILocale> appLocale;
    53       res = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
    54       if (NS_SUCCEEDED(res)) {
    55         res = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), 
    56 			             localeStr);
    57         if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
    58           mAppLocale.Assign(localeStr); // cache app locale name
    59         }
    60       }
    61     }
    62   }
    63   else {
    64     res = locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), localeStr);
    65   }
    67   // Get LCID and charset name from locale, if available
    68   if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
    69     mLocale.Assign(localeStr); // cache locale name
    70     res = nsWin32Locale::GetPlatformLocale(mLocale, (LCID *) &mLCID);
    71   }
    73   return res;
    74 }
    76 // performs a locale sensitive date formatting operation on the time_t parameter
    77 nsresult nsDateTimeFormatWin::FormatTime(nsILocale* locale, 
    78                                          const nsDateFormatSelector  dateFormatSelector, 
    79                                          const nsTimeFormatSelector timeFormatSelector, 
    80                                          const time_t  timetTime, 
    81                                          nsAString& stringOut)
    82 {
    83   return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, localtime( &timetTime ), stringOut);
    84 }
    86 // performs a locale sensitive date formatting operation on the struct tm parameter
    87 nsresult nsDateTimeFormatWin::FormatTMTime(nsILocale* locale, 
    88                                            const nsDateFormatSelector  dateFormatSelector, 
    89                                            const nsTimeFormatSelector timeFormatSelector, 
    90                                            const struct tm*  tmTime, 
    91                                            nsAString& stringOut)
    92 {
    93   SYSTEMTIME system_time;
    94   DWORD dwFlags_Date = 0, dwFlags_Time = 0;
    95   int dateLen, timeLen;
    96   char16_t dateBuffer[NSDATETIMEFORMAT_BUFFER_LEN], timeBuffer[NSDATETIMEFORMAT_BUFFER_LEN];
    98   // set up locale data
    99   (void) Initialize(locale);
   101   // Map tm to SYSTEMTIME
   102   system_time.wYear = 1900 + tmTime->tm_year;
   103   system_time.wMonth = tmTime->tm_mon + 1;
   104   system_time.wDayOfWeek = tmTime->tm_wday;
   105   system_time.wDay = tmTime->tm_mday;
   106   system_time.wHour = tmTime->tm_hour;
   107   system_time.wMinute = tmTime->tm_min;
   108   system_time.wSecond = tmTime->tm_sec;
   109   system_time.wMilliseconds = 0;
   111   // Map to WinAPI date format
   112   switch (dateFormatSelector) {
   113   case kDateFormatLong:
   114     dwFlags_Date = DATE_LONGDATE;
   115     break;
   116   case kDateFormatShort:
   117     dwFlags_Date = DATE_SHORTDATE;
   118     break;
   119   case kDateFormatWeekday:
   120     dwFlags_Date = 0;
   121     break;
   122   case kDateFormatYearMonth:
   123     dwFlags_Date = 0;     // TODO:only availabe NT5
   124     break;
   125   }
   127   // Map to WinAPI time format
   128   switch (timeFormatSelector) {
   129   case kTimeFormatSeconds:
   130     dwFlags_Time = 0;
   131     break;
   132   case kTimeFormatNoSeconds:
   133     dwFlags_Time = TIME_NOSECONDS;
   134     break;
   135   case kTimeFormatSecondsForce24Hour:
   136     dwFlags_Time = TIME_FORCE24HOURFORMAT;
   137     break;
   138   case kTimeFormatNoSecondsForce24Hour:
   139     dwFlags_Time = TIME_NOSECONDS + TIME_FORCE24HOURFORMAT;
   140     break;
   141   }
   143   // Call GetDateFormatW
   144   if (dateFormatSelector == kDateFormatNone) {
   145     dateLen = 0;
   146   }
   147   else {
   148     if (dateFormatSelector == kDateFormatYearMonth) {
   149       dateLen = nsGetDateFormatW(0, &system_time, "yyyy/MM", 
   150                                  dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
   151     }
   152     else if (dateFormatSelector == kDateFormatWeekday) {
   153       dateLen = nsGetDateFormatW(0, &system_time, "ddd", 
   154                                  dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
   155     }
   156     else {
   157       dateLen = nsGetDateFormatW(dwFlags_Date, &system_time, nullptr,
   158                                  dateBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
   159     }
   160     if (dateLen != 0) {
   161       dateLen--;  // Since the count includes the terminating null.
   162     }
   163   }
   165   // Call GetTimeFormatW
   166   if (timeFormatSelector == kTimeFormatNone) {
   167     timeLen = 0;
   168   }
   169   else {
   170     timeLen = nsGetTimeFormatW(dwFlags_Time, &system_time, nullptr, 
   171                                timeBuffer, NSDATETIMEFORMAT_BUFFER_LEN);
   172     if (timeLen != 0) {
   173       timeLen--;  // Since the count includes the terminating null.
   174     }
   175   }
   177   NS_ASSERTION(NSDATETIMEFORMAT_BUFFER_LEN >= (uint32_t) (dateLen + 1), "internal date buffer is not large enough");
   178   NS_ASSERTION(NSDATETIMEFORMAT_BUFFER_LEN >= (uint32_t) (timeLen + 1), "internal time buffer is not large enough");
   180   // Copy the result
   181   stringOut.Truncate();
   182   if (dateLen != 0 && timeLen != 0) {
   183     stringOut.Assign(dateBuffer, dateLen);
   184     stringOut.Append((char16_t *)(L" "), 1);
   185     stringOut.Append(timeBuffer, timeLen);
   186   }
   187   else if (dateLen != 0 && timeLen == 0) {
   188     stringOut.Assign(dateBuffer, dateLen);
   189   }
   190   else if (dateLen == 0 && timeLen != 0) {
   191     stringOut.Assign(timeBuffer, timeLen);
   192   }
   194   return NS_OK;
   195 }
   197 // performs a locale sensitive date formatting operation on the PRTime parameter
   198 nsresult nsDateTimeFormatWin::FormatPRTime(nsILocale* locale, 
   199                                            const nsDateFormatSelector  dateFormatSelector, 
   200                                            const nsTimeFormatSelector timeFormatSelector, 
   201                                            const PRTime  prTime, 
   202                                            nsAString& stringOut)
   203 {
   204   PRExplodedTime explodedTime;
   205   PR_ExplodeTime(prTime, PR_LocalTimeParameters, &explodedTime);
   207   return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut);
   208 }
   210 // performs a locale sensitive date formatting operation on the PRExplodedTime parameter
   211 nsresult nsDateTimeFormatWin::FormatPRExplodedTime(nsILocale* locale, 
   212                                                    const nsDateFormatSelector  dateFormatSelector, 
   213                                                    const nsTimeFormatSelector timeFormatSelector, 
   214                                                    const PRExplodedTime*  explodedTime, 
   215                                                    nsAString& stringOut)
   216 {
   217   struct tm  tmTime;
   218   memset( &tmTime, 0, sizeof(tmTime) );
   220   tmTime.tm_yday = explodedTime->tm_yday;
   221   tmTime.tm_wday = explodedTime->tm_wday;
   222   tmTime.tm_year = explodedTime->tm_year;
   223   tmTime.tm_year -= 1900;
   224   tmTime.tm_mon = explodedTime->tm_month;
   225   tmTime.tm_mday = explodedTime->tm_mday;
   226   tmTime.tm_hour = explodedTime->tm_hour;
   227   tmTime.tm_min = explodedTime->tm_min;
   228   tmTime.tm_sec = explodedTime->tm_sec;
   230   return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut);
   231 }
   233 int nsDateTimeFormatWin::nsGetTimeFormatW(DWORD dwFlags, const SYSTEMTIME *lpTime,
   234                                           const char* format, char16_t *timeStr, int cchTime)
   235 {
   236   int len = 0;
   237   len = GetTimeFormatW(mLCID, dwFlags, lpTime, 
   238                        format ?
   239                        NS_ConvertASCIItoUTF16(format).get() :
   240                        nullptr,
   241                        (LPWSTR) timeStr, cchTime);
   242   return len;
   243 }
   245 int nsDateTimeFormatWin::nsGetDateFormatW(DWORD dwFlags, const SYSTEMTIME *lpDate,
   246                                           const char* format, char16_t *dateStr, int cchDate)
   247 {
   248   int len = 0;
   249   len = GetDateFormatW(mLCID, dwFlags, lpDate, 
   250                        format ? NS_ConvertASCIItoUTF16(format).get() : nullptr,
   251                        (LPWSTR) dateStr, cchDate);
   252   return len;
   253 }

mercurial