intl/locale/src/windows/nsDateTimeFormatWin.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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

mercurial