intl/locale/src/windows/nsDateTimeFormatWin.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:50f0853713ef
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/. */
5
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"
14
15
16 #define NSDATETIMEFORMAT_BUFFER_LEN 80
17
18 NS_IMPL_ISUPPORTS(nsDateTimeFormatWin, nsIDateTimeFormat)
19
20
21 // init this interface to a specified locale
22 nsresult nsDateTimeFormatWin::Initialize(nsILocale* locale)
23 {
24 nsAutoString localeStr;
25 nsresult res = NS_OK;
26
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 }
43
44 // default LCID (en-US)
45 mLCID = 1033;
46
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 }
66
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 }
72
73 return res;
74 }
75
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 }
85
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];
97
98 // set up locale data
99 (void) Initialize(locale);
100
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;
110
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 }
126
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 }
142
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 }
164
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 }
176
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");
179
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 }
193
194 return NS_OK;
195 }
196
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);
206
207 return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut);
208 }
209
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) );
219
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;
229
230 return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut);
231 }
232
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 }
244
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