00001 /******************************************************************************* 00002 00003 @file UDateFormat.d 00004 00005 Copyright (c) 2004 Kris Bell 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for damages 00009 of any kind arising from the use of this software. 00010 00011 Permission is hereby granted to anyone to use this software for any 00012 purpose, including commercial applications, and to alter it and/or 00013 redistribute it freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must 00016 not claim that you wrote the original software. If you use this 00017 software in a product, an acknowledgment within documentation of 00018 said product would be appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must 00021 not be misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any distribution 00024 of the source. 00025 00026 4. Derivative works are permitted, but they must carry this notice 00027 in full and credit the original source. 00028 00029 00030 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00031 00032 00033 @version Initial version, November 2004 00034 @author Kris 00035 00036 Note that this package and documentation is built around the ICU 00037 project (http://oss.software.ibm.com/icu/). Below is the license 00038 statement as specified by that software: 00039 00040 00041 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00042 00043 00044 ICU License - ICU 1.8.1 and later 00045 00046 COPYRIGHT AND PERMISSION NOTICE 00047 00048 Copyright (c) 1995-2003 International Business Machines Corporation and 00049 others. 00050 00051 All rights reserved. 00052 00053 Permission is hereby granted, free of charge, to any person obtaining a 00054 copy of this software and associated documentation files (the 00055 "Software"), to deal in the Software without restriction, including 00056 without limitation the rights to use, copy, modify, merge, publish, 00057 distribute, and/or sell copies of the Software, and to permit persons 00058 to whom the Software is furnished to do so, provided that the above 00059 copyright notice(s) and this permission notice appear in all copies of 00060 the Software and that both the above copyright notice(s) and this 00061 permission notice appear in supporting documentation. 00062 00063 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00064 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00065 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 00066 OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 00067 HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 00068 INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING 00069 FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 00070 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 00071 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00072 00073 Except as contained in this notice, the name of a copyright holder 00074 shall not be used in advertising or otherwise to promote the sale, use 00075 or other dealings in this Software without prior written authorization 00076 of the copyright holder. 00077 00078 ---------------------------------------------------------------------- 00079 00080 All trademarks and registered trademarks mentioned herein are the 00081 property of their respective owners. 00082 00083 *******************************************************************************/ 00084 00085 module mango.icu.UDateFormat; 00086 00087 private import mango.icu.ICU, 00088 mango.icu.UString, 00089 mango.icu.UCalendar, 00090 mango.icu.UNumberFormat; 00091 00092 /******************************************************************************* 00093 00094 UDateFormat consists of functions that convert dates and 00095 times from their internal representations to textual form and back 00096 again in a language-independent manner. Converting from the internal 00097 representation (milliseconds since midnight, January 1, 1970) to text 00098 is known as "formatting," and converting from text to millis is known 00099 as "parsing." We currently define one concrete structure UDateFormat, 00100 which can handle pretty much all normal date formatting and parsing 00101 actions. 00102 00103 UDateFormat helps you to format and parse dates for any locale. 00104 Your code can be completely independent of the locale conventions 00105 for months, days of the week, or even the calendar format: lunar 00106 vs. solar. 00107 00108 See <A HREF="http://oss.software.ibm.com/icu/apiref/udat_8h.html"> 00109 this page</A> for full details. 00110 00111 *******************************************************************************/ 00112 00113 private class UDateFormat : ICU 00114 { 00115 private Handle handle; 00116 00117 alias UCalendar.UDate UDate; 00118 00119 typedef void* UFieldPos; 00120 00121 public enum Style 00122 { 00123 Full, 00124 Long, 00125 Medium, 00126 Short, 00127 Default = Medium, 00128 None = -1, 00129 Ignore = -2 00130 }; 00131 00132 public enum Field 00133 { 00134 EraField = 0, 00135 YearField = 1, 00136 MonthField = 2, 00137 DateField = 3, 00138 HourOfDay1Field = 4, 00139 HourOfDay0Field = 5, 00140 MinuteField = 6, 00141 SecondField = 7, 00142 FractionalSecondField = 8, 00143 DayOfWeekField = 9, 00144 DayOfYearField = 10, 00145 DayOfWeekInMonthField = 11, 00146 WeekOfYearField = 12, 00147 WeekOfMonthField = 13, 00148 AmPmField = 14, 00149 Hour1Field = 15, 00150 Hour0Field = 16, 00151 TimezoneField = 17, 00152 YearWoyField = 18, 00153 DowLocalField = 19, 00154 ExtendedYearField = 20, 00155 JulianDayField = 21, 00156 MillisecondsInDayField = 22, 00157 TimezoneRfcField = 23, 00158 FieldCount = 24 00159 }; 00160 00161 private enum Symbol 00162 { 00163 Eras, 00164 Months, 00165 ShortMonths, 00166 Weekdays, 00167 ShortWeekdays, 00168 AmPms, 00169 LocalizedChars 00170 }; 00171 00172 00173 /*********************************************************************** 00174 00175 Open a new UDateFormat for formatting and parsing dates 00176 and time. 00177 00178 ***********************************************************************/ 00179 00180 this (Style time, Style date, inout ULocale locale, inout UTimeZone tz, UText pattern) 00181 { 00182 Error e; 00183 00184 handle = udat_open (time, date, toString(locale.name), tz.name, tz.name.length, pattern.get, pattern.length, e); 00185 testError (e, "failed to create DateFormat"); 00186 } 00187 00188 /*********************************************************************** 00189 00190 Close a UDateFormat 00191 00192 ***********************************************************************/ 00193 00194 ~this () 00195 { 00196 udat_close (handle); 00197 } 00198 00199 /*********************************************************************** 00200 00201 Format a date using an UDateFormat 00202 00203 ***********************************************************************/ 00204 00205 void format (UString dst, UDate date, UFieldPos p = null) 00206 { 00207 uint fmat (wchar* result, uint len, inout Error e) 00208 { 00209 return udat_format (handle, date, result, len, p, e); 00210 } 00211 00212 dst.format (&fmat, "date format failed"); 00213 } 00214 00215 /*********************************************************************** 00216 00217 Parse a string into an date/time using a UDateFormat 00218 00219 ***********************************************************************/ 00220 00221 UDate parse (UText src, uint* index=null) 00222 { 00223 Error e; 00224 00225 UDate x = udat_parse (handle, src.content, src.len, index, e); 00226 testError (e, "failed to parse date"); 00227 return x; 00228 } 00229 00230 /*********************************************************************** 00231 00232 Set the UCalendar associated with an UDateFormat. A 00233 UDateFormat uses a UCalendar to convert a raw value 00234 to, for example, the day of the week. 00235 00236 ***********************************************************************/ 00237 00238 void setCalendar (UCalendar c) 00239 { 00240 udat_setCalendar (handle, c.handle); 00241 } 00242 00243 /*********************************************************************** 00244 00245 Get the UCalendar associated with this UDateFormat 00246 00247 ***********************************************************************/ 00248 00249 UCalendar getCalendar () 00250 { 00251 Handle h = udat_getCalendar (handle); 00252 return new UCalendar (h); 00253 } 00254 00255 /*********************************************************************** 00256 00257 Set the UNumberFormat associated with an UDateFormat.A 00258 UDateFormat uses a UNumberFormat to format numbers within 00259 a date, for example the day number. 00260 00261 ***********************************************************************/ 00262 00263 void setNumberFormat (UNumberFormat n) 00264 { 00265 udat_setCalendar (handle, n.handle); 00266 } 00267 00268 /*********************************************************************** 00269 00270 Get the year relative to which all 2-digit years are 00271 interpreted 00272 00273 ***********************************************************************/ 00274 00275 UDate getTwoDigitYearStart () 00276 { 00277 Error e; 00278 00279 UDate x = udat_get2DigitYearStart (handle, e); 00280 testError (e, "failed to get two digit year start"); 00281 return x; 00282 } 00283 00284 /*********************************************************************** 00285 00286 Set the year relative to which all 2-digit years are 00287 interpreted 00288 00289 ***********************************************************************/ 00290 00291 void setTwoDigitYearStart (UDate start) 00292 { 00293 Error e; 00294 00295 udat_set2DigitYearStart (handle, start, e); 00296 testError (e, "failed to set two digit year start"); 00297 } 00298 00299 /*********************************************************************** 00300 00301 Extract the pattern from a UDateFormat 00302 00303 ***********************************************************************/ 00304 00305 void getPattern (UString dst, bool localize) 00306 { 00307 uint fmat (wchar* result, uint len, inout Error e) 00308 { 00309 return udat_toPattern (handle, localize, result, len, e); 00310 } 00311 00312 dst.format (&fmat, "failed to retrieve date format pattern"); 00313 } 00314 00315 /*********************************************************************** 00316 00317 Set the pattern for a UDateFormat 00318 00319 ***********************************************************************/ 00320 00321 void setPattern (UText pattern, bool localized) 00322 { 00323 udat_applyPattern (handle, localized, pattern.get, pattern.length); 00324 } 00325 00326 /*********************************************************************** 00327 00328 Specify whether an UDateFormat will perform lenient parsing. 00329 00330 ***********************************************************************/ 00331 00332 void setLenient (bool yes) 00333 { 00334 udat_setLenient (handle, yes); 00335 } 00336 00337 /*********************************************************************** 00338 00339 Determine if an UDateFormat will perform lenient parsing. 00340 00341 ***********************************************************************/ 00342 00343 bool isLenient () 00344 { 00345 return cast(bool) (udat_isLenient (handle) != 0); 00346 } 00347 00348 00349 /*********************************************************************** 00350 00351 Bind the ICU functions from a shared library. This is 00352 complicated by the issues regarding D and DLLs on the 00353 Windows platform 00354 00355 ***********************************************************************/ 00356 00357 private static void* library; 00358 00359 /*********************************************************************** 00360 00361 ***********************************************************************/ 00362 00363 private static extern (C) 00364 { 00365 Handle function (uint, uint, char*, wchar*, uint, wchar*, uint, inout Error) udat_open; 00366 void function (Handle) udat_close; 00367 uint function (Handle, UDate, wchar*, uint, UFieldPos, inout Error) udat_format; 00368 UDate function (Handle, wchar*, uint, uint*, inout Error) udat_parse; 00369 void function (Handle, Handle) udat_setCalendar; 00370 void function (Handle, Handle) udat_setNumberFormat; 00371 UDate function (Handle, inout Error) udat_get2DigitYearStart; 00372 void function (Handle, UDate, inout Error) udat_set2DigitYearStart; 00373 uint function (Handle, byte, wchar*, uint, inout Error) udat_toPattern; 00374 void function (Handle, byte, wchar*, uint) udat_applyPattern; 00375 void function (Handle, byte) udat_setLenient; 00376 byte function (Handle) udat_isLenient; 00377 Handle function (Handle) udat_getCalendar; 00378 } 00379 00380 /*********************************************************************** 00381 00382 ***********************************************************************/ 00383 00384 static FunctionLoader.Bind[] targets = 00385 [ 00386 {cast(void**) &udat_open, "udat_open"}, 00387 {cast(void**) &udat_close, "udat_close"}, 00388 {cast(void**) &udat_format, "udat_format"}, 00389 {cast(void**) &udat_parse, "udat_parse"}, 00390 {cast(void**) &udat_setCalendar, "udat_setCalendar"}, 00391 {cast(void**) &udat_setNumberFormat, "udat_setNumberFormat"}, 00392 {cast(void**) &udat_get2DigitYearStart, "udat_get2DigitYearStart"}, 00393 {cast(void**) &udat_set2DigitYearStart, "udat_set2DigitYearStart"}, 00394 {cast(void**) &udat_toPattern, "udat_toPattern"}, 00395 {cast(void**) &udat_applyPattern, "udat_applyPattern"}, 00396 {cast(void**) &udat_setLenient, "udat_setLenient"}, 00397 {cast(void**) &udat_isLenient, "udat_isLenient"}, 00398 {cast(void**) &udat_getCalendar, "udat_getCalendar"}, 00399 ]; 00400 00401 /*********************************************************************** 00402 00403 ***********************************************************************/ 00404 00405 static this () 00406 { 00407 library = FunctionLoader.bind (icuin, targets); 00408 } 00409 00410 /*********************************************************************** 00411 00412 ***********************************************************************/ 00413 00414 static ~this () 00415 { 00416 FunctionLoader.unbind (library); 00417 } 00418 } 00419 00420