• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1---
2layout: default
3title: Formatting Dates and Times
4nav_order: 2
5parent: Formatting
6has_children: true
7---
8<!--
9© 2020 and later: Unicode, Inc. and others.
10License & terms of use: http://www.unicode.org/copyright.html
11-->
12
13# Formatting Dates and Times
14{: .no_toc }
15
16## Contents
17{: .no_toc .text-delta }
18
191. TOC
20{:toc}
21
22---
23
24## Formatting Dates and Times Overview
25
26Date and time formatters are used to convert dates and times from their internal
27representations to textual form and back again in a language-independent manner.
28The date and time formatters use `UDate`, which is the internal representation.
29Converting from the internal representation (milliseconds since midnight,
30January 1, 1970) to text is known as "formatting," and converting from text to
31milliseconds is known as "parsing." These processes involve two mappings:
32
33*   A mapping between a point in time (`UDate`) and a set of calendar fields,
34    which in turn depends on:
35    *   The rules of a particular calendar system (e.g. Gregorian, Buddhist,
36        Chinese Lunar)
37    *   The time zone
38*   A mapping between a set of calendar fields and a formatted textual
39    representation, which depends on the fields selected for display, their
40    display style, and the conventions of a particular locale.
41
42## `DateFormat`
43
44`DateFormat` helps format and parse dates for any locale. Your code can be
45completely independent of the locale conventions for months, days of the week,
46or calendar format.
47
48### Formatting Dates
49
50The `DateFormat` interface in ICU enables you to format a `Date` in milliseconds
51into a string representation of the date. It also parses the string back to the
52internal `Date` representation in milliseconds.
53
54```cpp
55DateFormat* df = DateFormat::createDateInstance();
56UnicodeString myString;
57UDate myDateArr[] = { 0.0, 100000000.0, 2000000000.0 };
58for (int32_t i = 0; i < 3; ++i) {
59  myString.remove();
60  cout << df->format( myDateArr[i], myString ) << endl;
61}
62```
63
64To format a date for a different `Locale`, specify it in the call to:
65
66```cpp
67DateFormat* df = DateFormat::createDateInstance
68   ( DateFormat::SHORT, Locale::getFrance());
69```
70
71### Parsing Dates
72
73Use a `DateFormat` to parse also:
74
75```cpp
76UErrorCode status = ZERO_ERROR;
77UDate myDate = df->parse(myString, status);
78```
79
80When numeric fields abut one another directly, with no intervening delimiter
81characters, they constitute a run of abutting numeric fields. Such runs are
82parsed specially. For example, the format `"HHmmss"` parses the input text
83"123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to
84parse "1234". In other words, the leftmost field of the run is flexible, while
85the others keep a fixed width. If the parse fails anywhere in the run, then the
86leftmost field is shortened by one character, and the entire run is parsed
87again. This is repeated until either the parse succeeds or the leftmost field is
88one character in length. If the parse still fails at that point, the parse of
89the run fails.
90
91### Producing Normal Date Formats for a Locale
92
93Use `createDateInstance` to produce the normal date format for that country. There
94are other static factory methods available. Use `createTimeInstance` to produce
95the normal time format for that country. Use `createDateTimeInstance` to produce a
96`DateFormat` that formats both date and time. You can pass different options to
97these factory methods to control the length of the result; from `SHORT` to `MEDIUM`
98to `LONG` to `FULL`. The exact result depends on the locale, but generally:
99
1001.  `SHORT` is numeric, such as 12/13/52 or 3:30pm
101
1022.  `MEDIUM` is longer, such as Jan. 12, 1952
103
1043.  `LONG` is longer, such as January 12, 1952 or 3:30:32pm
105
1064.  `FULL` is completely specified, such as Tuesday, April 12, 1952 AD or
107    3:30:42pm PST
108
109For more general flexibility, the [`DateTimePatternGenerator`](index#datetimepatterngenerator)
110can map a custom selection of time and date fields, along with various display styles for
111those fields, to a locale-appropriate format that can then be set as the format to use by the `DateFormat`.
112
113### Producing Relative Date Formats for a Locale
114
115ICU currently provides limited support for formatting dates using a “relative”
116style, specified using `RELATIVE_SHORT`, `RELATIVE_MEDIUM`, `RELATIVE_LONG` or
117`RELATIVE_FULL`. As currently implemented, relative date formatting only affects
118the formatting of dates within a limited range of calendar days before or after
119the current date, based on the CLDR `<field type="day">`/`<relative>` data: For
120example, in English, "Yesterday", "Today", and "Tomorrow". Within this range,
121the specific relative style currently makes no difference. Outside of this
122range, relative dates are formatted using the corresponding non-relative style
123(`SHORT`, `MEDIUM`, etc.). Relative time styles are not currently supported, and
124behave just like the corresponding non-relative style.
125
126### Setting Time Zones
127
128You can set the time zone on the format. If you want more control over the
129format or parsing, cast the `DateFormat` you get from the factory methods to a
130`SimpleDateFormat`. This works for the majority of countries.
131
132> :point_right: **Note**: *Remember to check `getDynamicClassID()` before carrying out the cast.*
133
134### Working with Positions
135
136You can also use forms of the parse and format methods with `ParsePosition` and
137`FieldPosition` to enable you to:
138
1391.  Progressively parse through pieces of a string.
140
1412.  Align any particular field, or find out where it is for selection on the
142    screen.
143
144## `SimpleDateFormat`
145
146`SimpleDateFormat` is a concrete class used for formatting and parsing dates in a
147language-independent manner. It allows for formatting, parsing, and
148normalization. It formats or parses a date or time, which is the standard
149milliseconds since 24:00 GMT, Jan. 1, 1970.
150
151`SimpleDateFormat` is the only built-in implementation of `DateFormat`. It provides
152a programmable interface that can be used to produce formatted dates and times
153in a wide variety of formats. The formats include almost all of the most common
154ones.
155
156Create a date-time formatter using the following methods rather than
157constructing an instance of `SimpleDateFormat`. In this way, the program is
158guaranteed to get an appropriate formatting pattern of the locale.
159
1601.  `DateFormat::getInstance()`
161
1622.  `getDateInstance()`
163
1643.  `getDateTimeInstance()`
165
166If you need a more unusual pattern, construct a `SimpleDateFormat` directly and
167give it an appropriate pattern.
168
169### Date/Time Format Syntax
170
171A date pattern is a string of characters, where specific strings of characters
172are replaced with date and time data from a calendar when formatting or used to
173generate data for a calendar when parsing.
174
175The Date Field Symbol Table below contains the characters used in patterns to
176show the appropriate formats for a given locale, such as `yyyy` for the year.
177Characters may be used multiple times. For example, if `y` is used for the year,
178`"yy"` might produce "99", whereas `"yyyy"` produces "1999". For most numerical
179fields, the number of characters specifies the field width. For example, if `h` is
180the hour, `"h"` might produce "5", but `"hh"` produces "05". For some characters,
181the count specifies whether an abbreviated or full form should be used, but may
182have other choices, as given below.
183
184Two single quotes represents a literal single quote, either inside or outside
185single quotes. Text within single quotes is not interpreted in any way (except
186for two adjacent single quotes). Otherwise all ASCII letter from **a** to **z** and **A** to
187**Z** are reserved as syntax characters, and require quoting if they are to
188represent literal characters. In addition, certain ASCII punctuation characters
189may become variable in the future (eg `':'` being interpreted as the time
190separator and `'/'` as a date separator, and replaced by respective
191locale-sensitive characters in display).
192
193"Stand-alone" values refer to those designed to stand on their own independently, as opposed
194to being with other formatted values. "2nd quarter" would use the wide stand-alone
195format `"qqqq"`, whereas "2nd quarter 2007" would use the regular format `"QQQQ
196yyyy"`. For more information about format and stand-alone forms, see [CLDR Calendar Elements](https://www.unicode.org/reports/tr35/tr35-dates.html#months_days_quarters_eras).
197
198The pattern characters used in the Date Field Symbol Table are defined by CLDR; for more information see [CLDR Date Field Symbol Table](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table).
199
200Note that the examples may not reflect current CLDR data.
201
202#### Date Field Symbol Table
203
204| Symbol | Meaning | Pattern | Example Output |
205| --- | --- | --- | --- |
206| `G` | era designator | `G`, `GG`, or `GGG`<br/>`GGGG`<br/>`GGGGG` | AD<br/>Anno Domini<br/>A |
207| `y` | year | `yy`<br/>`y` or `yyyy` | 96<br/>1996 |
208| `Y` | year of "Week of Year" | `Y` | 1997 |
209| `u` | extended year | `u` | 4601 |
210| `U` | cyclic year name, as in Chinese lunar calendar | `U` | 甲子 |
211| `r` | related Gregorian year | `r` | 1996 |
212| `Q` | quarter | `Q`<br/>`QQ`<br/>`QQQ`<br/>`QQQQ`<br/>`QQQQQ` | 2<br/>02<br/>Q2<br/>2nd quarter<br/>2 |
213| `q` | stand-alone quarter | `q`<br/>`qq`<br/>`qqq`<br/>`qqqq`<br/>`qqqqq` | 2<br/>02<br/>Q2<br/>2nd quarter<br/>2 |
214| `M` | month in year | `M`<br/>`MM`<br/>`MMM`<br/>`MMMM`<br/>`MMMMM` | 9<br/>09<br/>Sep<br/>September<br/>S |
215| `L` | stand-alone month in year | `L`<br/>`LL`<br/>`LLL`<br/>`LLLL`<br/>`LLLLL` | 9<br/>09<br/>Sep<br/>September<br/>S |
216| `w` | week of year | `w`<br/>`ww` | 27<br/>27 |
217| `W` | week of month | `W` | 2 |
218| `d` | day in month | `d`<br/>`dd` | 2<br/>02 |
219| `D` | day of year | `D` | 189 |
220| `F` | day of week in month | `F` | 2 (2nd Wed in July) |
221| `g` | modified julian day | `g` | 2451334 |
222| `E` | day of week | `E,` `EE`, or `EEE`<br/>`EEEE`<br/>`EEEEE`<br/>`EEEEEE` | Tue<br/>Tuesday<br/>T<br/>Tu |
223| `e` | local day of week<br/>example: if Monday is 1st day, Tuesday is 2nd ) | `e` or `ee`<br/>`eee`<br/>`eeee`<br/>`eeeee`<br/>`eeeeee` | 2<br/>Tue<br/>Tuesday<br/>T<br/>Tu |
224| `c` | stand-alone local day of week | `c` or `cc`<br/>`ccc`<br/>`cccc`<br/>`ccccc`<br/>`cccccc` | 2<br/>Tue<br/>Tuesday<br/>T<br/>Tu |
225| `a` | am/pm marker | `a` | pm |
226| `h` | hour in am/pm (1~12) | `h`<br/>`hh` | 7<br/>07 |
227| `H` | hour in day (0~23) | `H`<br/>`HH` | 0<br/>00 |
228| `k` | hour in day (1~24) | `k`<br/>`kk` | 24<br/>24 |
229| `K` | hour in am/pm (0~11) | `K`<br/>`KK` | 0<br/>00 |
230| `m` | minute in hour | `m`<br/>`mm` | 4<br/>04 |
231| `s` | second in minute | `s`<br/>`ss` | 5<br/>05 |
232| `S` | fractional second - truncates (like other time fields)<br/>to the count of letters when formatting. Appends<br/>zeros if more than 3 letters specified. Truncates at<br/>three significant digits when parsing. | `S`<br/>`SS`<br/>`SSS`<br/>`SSSS` | 2<br/>23<br/>235<br/>2350 |
233| `A` | milliseconds in day | `A` | 61201235 |
234| `z` | Time Zone: specific non-location | `z`, `zz`, or `zzz`<br/>`zzzz` | PDT<br/>Pacific Daylight Time |
235| `Z` | Time Zone: ISO8601 basic hms? / RFC 822<br/>Time Zone: long localized GMT (=OOOO)<br/>TIme Zone: ISO8601 extended hms? (=XXXXX) | `Z`, `ZZ`, or `ZZZ`<br/>`ZZZZ`<br/>`ZZZZZ` | -0800<br/>GMT-08:00<br/>-08:00, -07:52:58, Z |
236| `O` | Time Zone: short localized GMT<br/>Time Zone: long localized GMT (=ZZZZ) | `O`<br/>`OOOO` | GMT-8<br/>GMT-08:00 |
237| `v` | Time Zone: generic non-location<br/>(falls back first to VVVV) | `v`<br/>`vvvv` | PT<br/>Pacific Time or Los Angeles Time |
238| `V` | Time Zone: short time zone ID<br/>Time Zone: long time zone ID<br/>Time Zone: time zone exemplar city<br/>Time Zone: generic location (falls back to OOOO) | `V`<br/>`VV`<br/>`VVV`<br/>`VVVV` | uslax<br/>America/Los_Angeles<br/>Los Angeles<br/>Los Angeles Time |
239| `X` | Time Zone: ISO8601 basic hm?, with Z for 0<br/>Time Zone: ISO8601 basic hm, with Z<br/>Time Zone: ISO8601 extended hm, with Z<br/>Time Zone: ISO8601 basic hms?, with Z<br/>Time Zone: ISO8601 extended hms?, with Z | `X`<br/>`XX`<br/>`XXX`<br/>`XXXX`<br/>`XXXXX` | -08, +0530, Z<br/>-0800, Z<br/>-08:00, Z<br/>-0800, -075258, Z<br/>-08:00, -07:52:58, Z |
240| `x` | Time Zone: ISO8601 basic hm?, without Z for 0<br/>Time Zone: ISO8601 basic hm, without Z<br/>Time Zone: ISO8601 extended hm, without Z<br/>Time Zone: ISO8601 basic hms?, without Z<br/>Time Zone: ISO8601 extended hms?, without Z | `x`<br/>`xx`<br/>`xxx`<br/>`xxxx`<br/>`xxxxx` | -08, +0530<br/>-0800<br/>-08:00<br/>-0800, -075258<br/>-08:00, -07:52:58 |
241| `'` | escape for text | `'` | (nothing) |
242| `' '` | two single quotes produce one | `' '` | ' |
243
244> :point_right: **Note**: *Any characters in the pattern that are not in the ranges of
245['a'..'z'] and ['A'..'Z'] will be treated as quoted text. For instance,
246characters like `':'`, `'.'`, `' '`, `'#'` and `'@'` will appear in the resulting time
247text even they are not enclosed within single quotes. The single quote is used to
248'escape' letters. Two single quotes in a row, whether inside or outside a quoted
249sequence, represent a 'real' single quote.*
250
251> :point_right: **Note**: *A pattern containing any invalid pattern letter results in a failing `UErrorCode`
252result during formatting or parsing.*
253
254| Format Pattern | Result |
255| --- | --- |
256| `"yyyy.MM.dd G 'at' HH:mm:ss zzz"` | "1996.07.10 AD at 15:08:56 PDT" |
257| `"EEE, MMM d, ''yy"` | "Wed, July 10, '96" |
258| `"h:mm a"` | "12:08 PM" |
259| `"hh 'o''clock' a, zzzz"` | "12 o'clock PM, Pacific Daylight Time" |
260| `"K:mm a, z"` | "0:00 PM, PST" |
261| `"yyyyy.MMMM.dd GGG hh:mm aaa"` | "01996.July.10 AD 12:08 PM" |
262
263### Time Zone Display Names
264
265ICU supports time zone display names defined by the LDML ([Unicode Locale Data
266Markup Language](http://www.unicode.org/reports/tr35/) ) specification. Since
267ICU 3.8, the vast majority of localized time zone names are no longer associated
268with individual time zones. Instead, a set of localized time zone names are
269associated with a *metazone* and one or more individual time zones are mapped to
270the same *metazone*. For example, *metazone* “America_Pacific” has its own
271display name data such as “PST” “PDT” “PT” “Pacific Standard Time” “Pacific
272Daylight Time” “Pacific Time” and these names are shared by multiple individual
273time zones “America/Los_Angeles”, “America/Vancouver”, “America/Tijuana” and so
274on. The mapping from individual time zone to *metazone* is not a simple 1-to-1
275mapping, but it changes time to time. For example, time zone
276America/Indiana/Tell_City” uses name data from *metazone* “America_Eastern”
277until April 2, 2006, but it changes to *metazone* “America_Central” after the
278date. So the display name used for “America/Indiana/Tell_City” before the date
279(e.g. “Eastern Time”) differs from the one after the date (e.g. “Central Time).
280
281> :point_right: **Note**: *Prior to ICU 3.8, a localized time zone name (except GMT format) and a time
282zone ID was in 1-to-1 relationship always. Therefore, a time zone name produced
283by `DateFormat` can be parsed back to the original time zone. This assumption no
284longer applies to ICU 3.8 and later releases for all time zone format types. If
285you program requires to roundtrip specific time zone ID, you must use the
286generic location format `VVVV` explained below.*
287
288There are several different display name types available in the LDML
289specification.
290
291#### Time Zone Display Name Types
292
293| Type | Description | Examples |
294| --- | --- | --- |
295| Generic non-location | Reflects wall time, suited for displaying recurring events, meetings or anywhere people do not want to be overly specific. Available in two length options – long and short. | Pacific Time<br/>PT |
296| Generic partial location | Reflects wall time, used as a fallback format when the generic non-location format is not specific enough. A generic partial location name is constructed from a generic non-location name with a location name. For example, “PT” is shared by multiple time zones via metazone “America_Pacific”. When GMT offset in the time zone at the given time differs from the preferred time zone of the metazone for the locale, location name is appended to generic non-location name to distinguish the time zone from the preferred zone. Available in two length options – long and short. | Pacific Time (Canada)<br/>PT (Yellowknife) |
297| Generic location | Reflects wall time, suited for populating choice list for time zones. If the time zone is the single time zone available in the region (country), the generic location name is constructed with the region name. Otherwise, the name is constructed from the region name and the city name. Unlike other format types, this name is unique per time zone. | United States (Los Angeles) Time<br/>Italy Time |
298| Specific non-location | Reflects a specific standard or daylight time. Available in two length options – long and short. | Pacific Standard Time<br/>PDT |
299| Localized GMT | A constant, specific offset from GMT in a localized form. | GMT-08:00 |
300| RFC822 GMT | A constant, specific offset from GMT in a locale insensitive format. | -0800 |
301
302Each format type in the above table is used as a primary type or a fallback in
303`SimpleDateFormat`. The table below explains how ICU time zone format pattern work
304and its characteristics.
305
306#### Time Zone Pattern Usage
307
308| Pattern | Behavior | Round-trip time at daylight transitions(\*) | Round-trip Time Zone | Suggested Usage |
309| --- | --- | --- | --- | --- |
310| `z`, `zz`, `zzz` | Short specific non-location format (e.g. “PST”). If the localized data is not available or the short abbreviation is not commonly used for the locale, localized GMT format is used (e.g. "GMT-08:00"). | yes | no | For displaying a time with a user friendly time zone name. |
311| `zzzz` | Long specific non-location format (e.g. “Pacific Standard Time”). If the localized data is not available, localized GMT format is used (e.g. "GMT-08:00"). | yes | no | Same as `z`, but longer format. |
312| `v` | Short generic non-location format (e.g. “PT”). If the localized data is not available or the short abbreviation is not commonly used for the locale, generic location format (e.g. “United States(Los Angeles) Time”) is used. If the localized data comes from metazone and the GMT offset at the given time in the specified time zone differs from the preferred time zone of the metazone for the locale, generic partial location format (e.g. “PT (Canada)”) is used. | no | no | For displaying a recurring wall time (e.g. events, meetings) or anywhere people do not want to be overly specific. |
313| `vvvv` | Long generic non-location format (e.g. “Pacific Time”). If the localized data is not available, generic location format (e.g. “United States(Los Angeles) Time”) is used. | no | no | Same as `v`, but longer format. |
314| `V` | Same as `z`, except using the short abbreviation even it is not commonly used for the locale. | yes | no | Same as `z`. |
315| `VVVV` | Generic location format (e.g. “United States (Los Angeles) Time”). | no | yes | For populating a choice list for time zones, because it supports 1-to-1 name/zone ID mapping and is more uniform than other text formats. Also, this is only the pattern supporting time zone round-trip. If your program requires to preserve the original time zone information, use this pattern. |
316| `Z`, `ZZ`, `ZZZ` | Localized GMT format (e.g. “GMT-08:00”). | yes | no | For displaying a time in UI in a uniformed manner. |
317| `ZZZZ` | RFC822 GMT format (e.g. “-0800”). | yes | no | For formatting a time for non-user-facing data. |
318
319\* At a transition from daylight saving time to standard time, there is a wall
320time interval occurs twice.
321
322## `DateTimePatternGenerator`
323
324The `DateTimePatternGenerator` class provides a way to map a request for a set of
325date/time fields, along with their width, to a locale-appropriate format
326pattern. The request is in the form of a “skeleton” which just contains pattern
327letters for the desired fields using the representation for the desired width.
328In a skeleton, anything other than a pattern letter is ignored, field order is
329insignificant, and there are two special additional pattern letters that may be
330used: `j` requests the preferred hour-cycle type for the locale (it gets mapped
331to one of `H`, `h`, `k`, or `K`); `J` is similar but requests no AM/PM marker
332even if the locale’s preferred hour-cycle type is `h` or `K`.
333
334For example, a skeleton of `“MMMMdjmm”` might result in the following format
335patterns for different locales:
336
337| locale | format pattern for skeleton `“MMMMdjmm”` | example              |
338| ------ | ---------------------------------------- | -------------------- |
339| en_US  | `"MMMM d  'at'  h:mm a"`                 | "April 2 at 5:00 PM" |
340| es_ES  | `"d 'de' MMMM, H:mm"`                    | "2 de abril, 17:00"  |
341| ja_JP  | `"M月d日 H:mm"`                            | "4月2日 17:00"         |
342
343The most important DateTimePatternGenerator methods are the varieties of
344getBestPattern.
345
346Note that the fields in the format pattern may be adjusted as appropriate for
347the locale and may not exactly match those in the skeleton. For example:
348
349*   In Russian (locale "ru"), the skeleton `"yMMMM"` will produce the format
350    pattern `"LLLL y"` (or `"LLLL y 'г'."`) since a month name without a day number
351    must be in nominative form, as indicated by `LLLL`.
352*   When using the Japanese calendar in the Japanese locale (locale
353    "ja@calendar=japanese"), the skeleton `"yMMMd"` will produce the format
354    pattern `"Gy年M月d日"` since the era must always be shown with the year in the
355    Japanese calendar.
356
357## `DateFormatSymbols`
358
359`DateFormatSymbols` is a public class for encapsulating localizable date-time
360formatting data, including time zone data. `DateFormatSymbols` is used by
361`DateFormat` and `SimpleDateFormat`.
362
363`DateFormatSymbols` specifies the exact character strings to use for various parts
364of a date or time For example, the names of the months and days of the week, the
365strings for AM and PM and the day of the week considered to be the first day of
366the week (used in drawing calendar grids) are controlled by `DateFormatSymbols`.
367
368Create a date-time formatter using the `createTimeInstance`, `createDateInstance`,
369or `createDateTimeInstance` methods in `DateFormat`. Each of these methods can
370return a date/time formatter initialized with a default format pattern, along
371with the date-time formatting data for a given or default locale. After a
372formatter is created, modify the format pattern using `applyPattern`.
373
374If you want to create a date-time formatter with a particular format pattern and
375locale, use one of the `SimpleDateFormat` constructors:
376
377```cpp
378UnicodeString aPattern("GyyyyMMddHHmmssSSZ", "");
379new SimpleDateFormat(aPattern, new DateFormatSymbols(Locale::getUS())
380```
381
382This loads the appropriate date-time formatting data from the locale.
383
384## Programming Examples
385
386See [date and time formatting examples](examples.md).
387