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