1--- 2layout: default 3title: Date and Time Formatting Examples 4nav_order: 1 5grand_parent: Formatting 6parent: Formatting Dates and Times 7--- 8<!-- 9© 2020 and later: Unicode, Inc. and others. 10License & terms of use: http://www.unicode.org/copyright.html 11--> 12 13# Date and Time Formatting Examples 14{: .no_toc } 15 16## Contents 17{: .no_toc .text-delta } 18 191. TOC 20{:toc} 21 22--- 23 24## Format 25 26The ICU DateFormat interface enables you to format a date in milliseconds into a 27string representation of the date. Also, the interface enables you to parse the 28string back to the internal date representation in milliseconds. 29 30### C++ 31 32```cpp 33DateFormat* df = DateFormat::createDateInstance(); 34UnicodeString myString; 35UDate myDateArr[] = { 0.0, 100000000.0, 2000000000.0 }; 36for (int32_t i = 0; i < 3; ++i) { 37 myString.remove(); 38 cout << df->format( myDateArr[i], myString ) << endl; 39} 40``` 41 42### C 43 44```c 45/* 1st example: format the dates in millis 100000000 and 2000000000 */ 46UErrorCode status=U_ZERO_ERROR; 47int32_t i, myStrlen=0; 48UChar* myString; 49UDate myDateArr[] = { 0.0, 100000000.0, 2000000000.0 }; // test values 50UDateFormat* df = udat_open(UCAL_DEFAULT, UCAL_DEFAULT, NULL, "GMT", &status); 51for (i = 0; i < 3; ++i) { 52 myStrlen = udat_format(df, myDateArr[i], NULL, myStrlen, NULL, &status); 53 if(status==U_BUFFER_OVERFLOW_ERROR){ 54 status=U_ZERO_ERROR; 55 myString=(UChar*)malloc(sizeof(UChar) * (myStrlen+1) ); 56 udat_format(df, myDateArr[i], myString, myStrlen+1, NULL, &status); 57 printf("%s\n", austrdup(myString) ); 58 /* austrdup( a function used to convert UChar* to char*) */ 59 free(myString); 60 } 61} 62``` 63 64## Parse 65 66To parse a date for a different locale, specify it in the locale call. This call 67creates a formatting object. 68 69### C++ 70 71```cpp 72DateFormat* df = DateFormat::createDateInstance 73 ( DateFormat::SHORT, Locale::getFrance()); 74``` 75 76### C 77 78```c 79/* 2nd example: parse a date with short French date/time formatter */ 80UDateFormat* df = udat_open(UDAT_SHORT, UDAT_SHORT, "fr_FR", "GMT", &status); 81UErrorCode status = U_ZERO_ERROR; 82int32_t parsepos=0; 83UDate myDate = udat_parse(df, myString, u_strlen(myString), &parsepos, 84&status); 85``` 86 87### Java 88 89```java 90import java.text.FieldPosition; 91import java.text.ParseException; 92import java.util.Calendar; 93import java.util.Date; 94import java.util.Locale; 95 96import com.ibm.icu.text.DateFormat; 97 98public class TestDateTimeFormat { 99 public void run() { 100 101 // Formatting Dates 102 103 DateFormat dfUS = DateFormat.getDateInstance(DateFormat.FULL, Locale.US); 104 DateFormat dfFrance = DateFormat.getDateInstance(DateFormat.FULL, Locale.FRANCE); 105 StringBuffer sb = new StringBuffer(); 106 Calendar c = Calendar.getInstance(); 107 Date d = c.getTime(); 108 sb = dfUS.format(d, sb, new FieldPosition(0)); 109 System.out.println(sb.toString()); 110 111 StringBuffer sbf = new StringBuffer(); 112 sbf = dfFrance.format(d, sbf, new FieldPosition(0)); 113 System.out.println(sbf.toString()); 114 115 StringBuffer sbg = new StringBuffer(); 116 DateFormat dfg = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT); 117 FieldPosition pos = new FieldPosition(DateFormat.MINUTE_FIELD); 118 sbg = dfg.format(d, sbg, pos); 119 System.out.println(sbg.toString()); 120 System.out.println(sbg.toString().substring(pos.getBeginIndex(), pos.getEndIndex())); 121 122 // Parsing Dates 123 124 String dateString_US = "Thursday, February 7, 2008"; 125 String dateString_FRANCE = "jeudi 7 février 2008"; 126 try { 127 Date parsedDate_US = dfUS.parse(dateString_US); 128 Date parsedDate_FRANCE = dfFrance.parse(dateString_FRANCE); 129 System.out.println(parsedDate_US.toString()); 130 System.out.println(parsedDate_FRANCE.toString()); 131 } catch (ParseException pe) { 132 System.out.println("Exception while parsing :" + pe); 133 } 134 } 135 136 public static void main(String args[]) { 137 new TestDateTimeFormat().run(); 138 } 139} 140``` 141 142## Getting Specific Date Fields 143 144To get specific fields of a date, you can use the FieldPosition function for C++ 145or UFieldPosition function for C. 146 147### C++ 148 149```cpp 150UErrorCode status = U_ZERO_ERROR; 151FieldPosition pos(DateFormat::YEAR_FIELD) 152UDate myDate = Calendar::getNow(); 153UnicodeString str; 154DateFormat* df = DateFormat::createDateInstance 155 ( DateFormat::LONG, Locale::getFrance()); 156 157df->format(myDate, str, pos, status); 158cout << pos.getBeginIndex() << "," << pos. getEndIndex() << endl; 159``` 160 161### C 162 163```c 164UErrorCode status = U_ZERO_ERROR; 165UFieldPosition pos; 166UChar *myString; 167int32_t myStrlen = 0; 168char buffer[1024]; 169 170 171pos.field = 1; /* Same as the DateFormat::EField enum */ 172UDateFormat* dfmt = udat_open(UCAL_DEFAULT, UCAL_DEFAULT, NULL, "PST", 173&status); 174myStrlen = udat_format(dfmt, myDate, NULL, myStrlen, &pos, &status); 175if (status==U_BUFFER_OVERFLOW_ERROR){ 176 status=U_ZERO_ERROR; 177 myString=(UChar*)malloc(sizeof(UChar) * (myStrlen+1) ); 178 udat_format(dfmt, myDate, myString, myStrlen+1, &pos, &status); 179} 180printf("date format: %s\n", u_austrcpy(buffer, myString)); 181buffer[pos.endIndex] = 0; // NULL terminate the string. 182printf("UFieldPosition position equals %s\n", &buffer[pos.beginIndex]); 183``` 184 185## DateTimePatternGenerator 186 187This class lets you get a different variety of patterns, such as month+day. The 188following illustrates this in Java, C++ and C. 189 190### Java 191 192```java 193// set up the generator 194DateTimePatternGenerator generator 195 = DateTimePatternGenerator.getInstance(locale); 196 197// get a pattern for an abbreviated month and day 198final String pattern = generator.getBestPattern("MMMd"); 199SimpleDateFormat formatter = new SimpleDateFormat(pattern, locale); 200 201// use it to format (or parse) 202String formatted = formatter.format(new Date()); 203// for French, the result is "13 sept." 204``` 205 206### C++ 207 208```cpp 209// set up the generator 210status = U_ZERO_ERROR; 211DateTimePatternGenerator *generator = DateTimePatternGenerator::createInstance( locale, status); 212if (U_FAILURE(status)) { 213 return; 214} 215 216// get a pattern for an abbreviated month and day 217UnicodeString pattern = generator->getBestPattern(UnicodeString("MMMd"), status); 218SimpleDateFormat *formatter = new SimpleDateFormat(pattern, locale, status); 219 220// use it to format (or parse) 221UnicodeString formatted; 222formatted = formatter->format(Calendar::getNow(), formatted, status); 223// for French, the result is "13 sept." 224``` 225 226### C 227 228```c 229const UChar skeleton[]= {'M', 'M', 'M', 'd', 0}; 230 231status=U_ZERO_ERROR; 232generator=udatpg_open(locale, &status); 233if(U_FAILURE(status)) { 234 return; 235 236} 237 238/* get a pattern for an abbreviated month and day */ 239length = udatpg_getBestPattern(generator, skeleton, 4, 240 pattern, patternCapacity, &status); 241formatter = udat_open(UDAT_IGNORE, UDAT_DEFAULT, locale, NULL, -1, 242 pattern, length, &status); 243 244/* use it to format (or parse) */ 245formattedCapacity = (int32_t)(sizeof(formatted)/sizeof((formatted)[0])); 246resultLen=udat_format(formatter, ucal_getNow(), formatted, formattedCapacity, 247 NULL, &status); 248/* for French, the result is "13 sept." */ 249``` 250 251## Changing the TimeZone Formatting Style 252 253It also contains some helper functions for parsing patterns. Here's an example 254of replacing the kind of timezone used in a pattern. 255 256### Java 257 258```cpp 259/** 260 * Replace the zone string with a different type, eg v's for z's, etc. 261 * <p>Called with a pattern, such as one gotten from 262 * <pre> 263 * String pattern = ((SimpleDateFormat) 264 * DateFormat.getTimeInstance(style, locale)).toPattern(); 265 * </pre> 266 * @param pattern original pattern to change, such as "HH:mm zzzz" 267 * @param newZone Must be: z, zzzz, Z, ZZZZ, v, vvvv, V, or VVVV 268 * @return 269 */ 270public String replaceZoneString(String pattern, String newZone) { 271 DateTimePatternGenerator.FormatParser formatParser = 272 new DateTimePatternGenerator.FormatParser(); 273 final List itemList = formatParser.set(pattern).getItems(); 274 boolean found = false; 275 for (int i = 0; i < itemList.size(); ++i) { 276 Object item = itemList.get(i); 277 if (item instanceof VariableField) { 278 // the first character of the variable field determines the type, 279 // according to CLDR. 280 String variableField = item.toString(); 281 switch (variableField.charAt(0)) { 282 case 'z': case 'Z': case 'v': case 'V': 283 if (!variableField.equals(newZone)) { 284 found = true; 285 itemList.set(i, new VariableField(newZone)); 286 } 287 break; 288 } 289 } 290 } 291 return found ? formatParser.toString() : pattern; 292} 293``` 294