[Unicode]  Technical Reports
 

Unicode Technical Standard #35

Unicode Locale Data Markup Language (LDML)
Part 4: Dates

Version 26
Editors Peter Edberg and other CLDR committee members

For the full header, summary, and status, see Part 1: Core.

Summary

This document describes parts of an XML format (vocabulary) for the exchange of structured locale data. This format is used in the Unicode Common Locale Data Repository.

This is a partial document, describing only those parts of the LDML that are relevant for date, time, and time zone formatting. For the other parts of the LDML see the main LDML document and the links above.

Status

This document has been reviewed by Unicode members and other interested parties, and has been approved for publication by the Unicode Consortium. This is a stable document and may be used as reference material or cited as a normative reference by other specifications.

A Unicode Technical Standard (UTS) is an independent specification. Conformance to the Unicode Standard does not imply conformance to any UTS.

Please submit corrigenda and other comments with the CLDR bug reporting form [Bugs]. Related information that is useful in understanding this document is found in the References. For the latest version of the Unicode Standard see [Unicode]. For a list of current Unicode Technical Reports see [Reports]. For more information about versions of the Unicode Standard, see [Versions].

Parts

The LDML specification is divided into the following parts:

Contents of Part 4, Dates

1 Overview: Dates Element, Supplemental Date and Calendar Information

<!ELEMENT dates (alias | (calendars?, fields?, timeZoneNames?, special*)) >

The LDML top-level <dates> element contains information regarding the format and parsing of dates and times, the formatting of date/time intervals, and the the naming of various calendar elements.

<!ELEMENT supplementalData ( …, calendarData?, calendarPreferenceData?, weekData?, timeData?, …, timezoneData?, …, metazoneInfo?, …, dayPeriodRuleSet?, metaZones?, primaryZones?, windowsZones?, …) >

The relevant top-level supplemental elements are listed above.

2 Calendar Elements

<!ELEMENT calendars (alias | (calendar*, special*)) >
<!ELEMENT calendar (alias | (months?, monthPatterns?, days?, quarters?, dayPeriods?, eras?, cyclicNameSets?, dateFormats?, timeFormats?, dateTimeFormats?, special*))>
<!ATTLIST calendar type NMTOKEN #REQUIRED >

The <calendars> element contains multiple <calendar> elements, each of which specifies the fields used for formatting and parsing dates and times according to the calendar specified by the type attribute (e.g. "gregorian", "buddhist", "islamic"). The behaviors for different calendars in a locale may share certain aspects, such as the names for weekdays. They differ in other respects; for example, the Japanese calendar is similar to the Gregorian calendar but has many more eras (one for each Emperor), and years are numbered within each era. All calendar data inherits either from the Gregorian calendar or other calendars in the same locale (and if not present there then from the parent up to root), or else inherits directly from the parent locale for certain calendars, so only data that differs from what would be inherited needs to be supplied. See Multiple Inheritance.

Each calendar provides—directly or indirectly—two general types of data:

Calendars that use cyclicNameSets and monthPatterns have additional symbols and distinct formats, and typically inherit these items (along with month names) from their parent locales, instead of inheriting them from Gregorian or generic data in the same locale.

2.1 Elements months, days, quarters, eras

<!ELEMENT months ( alias | (monthContext*, special*)) >
<!ELEMENT monthContext ( alias | (default*, monthWidth*, special*)) >
<!ATTLIST monthContext type ( format | stand-alone ) #REQUIRED >
<!ELEMENT monthWidth ( alias | (month*, special*)) >
<!ATTLIST monthWidth type ( abbreviated| narrow | wide) #REQUIRED >
<!ELEMENT month ( #PCDATA )* >
<!ATTLIST month type ( 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 ) #REQUIRED >
<!ATTLIST month yeartype ( standard | leap ) #IMPLIED >

<!ELEMENT days ( alias | (dayContext*, special*)) >
<!ELEMENT dayContext ( alias | (default*, dayWidth*, special*)) >
<!ATTLIST dayContext type ( format | stand-alone ) #REQUIRED >
<!ELEMENT dayWidth ( alias | (day*, special*)) >
<!ATTLIST dayWidth type NMTOKEN #REQUIRED >
<!ELEMENT day ( #PCDATA ) >
<!ATTLIST day type ( sun | mon | tue | wed | thu | fri | sat ) #REQUIRED >

<!ELEMENT quarters ( alias | (quarterContext*, special*)) >
<!ELEMENT quarterContext ( alias | (default*, quarterWidth*, special*)) >
<!ATTLIST quarterContext type ( format | stand-alone ) #REQUIRED >
<!ELEMENT quarterWidth ( alias | (quarter*, special*)) >
<!ATTLIST quarterWidth type NMTOKEN #REQUIRED >
<!ELEMENT quarter ( #PCDATA ) >
<!ATTLIST quarter type ( 1 | 2 | 3 | 4 ) #REQUIRED >

<!ELEMENT eras (alias | (eraNames?, eraAbbr?, eraNarrow?, special*)) >
<!ELEMENT eraNames ( alias | (era*, special*) ) >
<!ELEMENT eraAbbr ( alias | (era*, special*) ) >
<!ELEMENT eraNarrow ( alias | (era*, special*) ) >

The month and quarter names are identified numerically, starting at 1. The weekday names are identified with short strings, since there is no universally-accepted numeric designation.

Month, day, and quarter names may vary along two axes: the width and the context. The context is either format (the default), the form used within a date format string (such as "Saturday, November 12th", or stand-alone, the form used independently, such as in calendar headers. The width can be wide (the default), abbreviated, or narrow; for days only, the width can also be short, which is ideally between the abbreviated and narrow widths, but must be no longer than abbreviated and no shorter than narrow (if short day names are not explicitly specified, abbreviated day names are used instead). Note that for <monthPattern>, described in the next section:

The format values must be distinct for the wide, abbreviated, and short widths. However, values for the narrow width in either format or stand-alone contexts, as well as values for other widths in stand-alone contexts, need not be distinct; they might only be distinguished by context. For example, "S" may be used both for Saturday and for Sunday. The narrow width is typically used in calendar headers; it must be the shortest possible width, no more than one character (or grapheme cluster, or exemplar set element) in stand-alone values (not including punctuation), and the shortest possible widths (in terms of grapheme clusters) in format values. The short width (if present) is often the shortest unambiguous form.

Era names should be distinct within each of the widths, including narrow; there is less disambiguating information for them, and they are more likely to be used in a format that requires parsing.

The most important distinction to make between format and stand-alone forms is a grammatical distinction, for languages that require it. For example, many languages require that a month name without an associated day number be in the basic nominative form, while a month name with an associated day number should be in a different grammatical form: genitive, partitive, etc. Another common type of distinction between format and stand-alone involves capitalization; however, this can be controlled separately and more precisely using the <contextTransforms> element as described in ContextTransform Elements.

Due to aliases in root, the forms inherit "sideways". (See Multiple Inheritance.) For example, if the abbreviated format data for Gregorian does not exist in a language X (in the chain up to root), then it inherits from the wide format data in that same language X.

<monthContext type="format">
	<monthWidth type="abbreviated">
		<alias source="locale" path="../monthWidth[@type='wide']"/>
	</monthWidth>
	<monthWidth type="narrow">
		<alias source="locale" path="../../monthContext[@type='stand-alone']/monthWidth[@type='narrow']"/>
	</monthWidth>
	<monthWidth type="wide">
		<month type="1">1</month>
		...
		<month type="12">12</month>
	</monthWidth>
</monthContext>
<monthContext type="stand-alone">
	<monthWidth type="abbreviated">
		<alias source="locale" path="../../monthContext[@type='format']/monthWidth[@type='abbreviated']"/>
	</monthWidth>
	<monthWidth type="narrow">
		<month type="1">1</month>
		...
		<month type="12">12</month>
	</monthWidth>
	<monthWidth type="wide">
		<alias source="locale" path="../../monthContext[@type='format']/monthWidth[@type='wide']"/>
	</monthWidth>
</monthContext>

The yeartype attribute for months is used to distinguish alternate month names that would be displayed for certain calendars during leap years. The practical example of this usage occurs in the Hebrew calendar, where the 7th month "Adar" occurs in non-leap years, with the 6th month being skipped, but in leap years there are two months named "Adar I" and "Adar II". There are currently only two defined year types, standard (the implied default) and leap.

For era elements, an additional alt="variant" form may be supplied. This is primarily intended for use in the "gregorian" calendar, with which two parallel sets of era designations are used in some locales: one set with a religious reference (e.g. English BC/AD), and one set without (e.g. English BCE/CE). The most commonly-used set for the locale should be provided as the default, and the other set may be provided as the alt="variant" forms. See the example below.

Example:

  <calendar type="gregorian">
    <months>
      <monthContext type="format">
         <monthWidth type="wide">
            <month type="1">January</month>
            <month type="2">February</month>
...
            <month type="11">November</month>
            <month type="12">December</month>
        </monthWidth>
        <monthWidth type="abbreviated">
            <month type="1">Jan</month>
            <month type="2">Feb</month>
...
            <month type="11">Nov</month>
            <month type="12">Dec</month>
        </monthWidth>
       <monthContext type="stand-alone">
         <default type="wide"/>
         <monthWidth type="wide">
            <month type="1">Januaria</month>
            <month type="2">Februaria</month>
...
            <month type="11">Novembria</month>
            <month type="12">Decembria</month>
        </monthWidth>
        <monthWidth type="narrow">
            <month type="1">J</month>
            <month type="2">F</month>
...
            <month type="11">N</month>
            <month type="12">D</month>
        </monthWidth>
       </monthContext>
    </months>

    <days>
      <dayContext type="format">
         <dayWidth type="wide">
            <day type="sun">Sunday</day>
            <day type="mon">Monday</day>
...
            <day type="fri">Friday</day>
            <day type="sat">Saturday</day>
        </dayWidth>
        <dayWidth type="abbreviated">
            <day type="sun">Sun</day>
            <day type="mon">Mon</day>
...
            <day type="fri">Fri</day>
            <day type="sat">Sat</day>
        </dayWidth>
        <dayWidth type="narrow">
            <day type="sun">Su</day>
            <day type="mon">M</day>
...
            <day type="fri">F</day>
            <day type="sat">Sa</day>
        </dayWidth>
      </dayContext>
      <dayContext type="stand-alone">
        <dayWidth type="narrow">
            <day type="sun">S</day>
            <day type="mon">M</day>
...
            <day type="fri">F</day>
            <day type="sat">S</day>
        </dayWidth>
      </dayContext>
    </days>

    <quarters>
      <quarterContext type="format">
         <quarterWidth type="abbreviated">
            <quarter type="1">Q1</quarter>
            <quarter type="2">Q2</quarter>
            <quarter type="3">Q3</quarter>
            <quarter type="4">Q4</quarter>
        </quarterWidth>
        <quarterWidth type="wide">
            <quarter type="1">1st quarter</quarter>
            <quarter type="2">2nd quarter</quarter>
            <quarter type="3">3rd quarter</quarter>
            <quarter type="4">4th quarter</quarter>
        </quarterWidth>
      </quarterContext>
    </quarters>

    <eras>
       <eraAbbr>
        <era type="0">BC</era>
        		<era type="0" alt="variant">BCE</era>
        <era type="1">AD</era>
        <era type="1" alt="variant">CE</era>
       </eraAbbr>
       <eraNames>
        <era type="0">Before Christ</era>
        		<era type="0" alt="variant">Before Common Era</era>
        <era type="1">Anno Domini</era>
        		<era type="1" alt="variant">Common Era</era>
       </eraNames>
       <eraNarrow>
        <era type="0">B</era>
        <era type="1">A</era>
       </eraNarrow>
    </eras>

2.2 Elements monthPatterns, cyclicNameSets

<!ELEMENT monthPatterns ( alias | (monthPatternContext*, special*)) >
<!ELEMENT monthPatternContext ( alias | (monthPatternWidth*, special*)) >
<!ATTLIST monthPatternContext type ( format | stand-alone | numeric ) #REQUIRED >
<!ELEMENT monthPatternWidth ( alias | (monthPattern*, special*)) >
<!ATTLIST monthPatternWidth type ( abbreviated| narrow | wide | all ) #REQUIRED >
<!ELEMENT monthPattern ( #PCDATA ) >
<!ATTLIST monthPattern type ( leap | standardAfterLeap | combined ) #REQUIRED >

<!ELEMENT cyclicNameSets ( alias | (cyclicNameSet*, special*)) >
<!ELEMENT cyclicNameSet ( alias | (cyclicNameContext*, special*)) >
<!ATTLIST cyclicNameSet type ( years | months | days | dayParts | zodiacs | solarTerms ) #REQUIRED >
<!ELEMENT cyclicNameContext ( alias | (cyclicNameWidth*, special*)) >
<!ATTLIST cyclicNameContext type ( format | stand-alone ) #REQUIRED >
<!ELEMENT cyclicNameWidth ( alias | (cyclicName*, special*)) >
<!ATTLIST cyclicNameWidth type ( abbreviated | narrow | wide ) #REQUIRED >
<!ELEMENT cyclicName ( #PCDATA ) >
<!ATTLIST cyclicName type NMTOKEN #REQUIRED >

The Chinese lunar calendar can insert a leap month after nearly any month of its year; when this happens, the month takes the name of the preceding month plus a special marker. The Hindu lunar calendars can insert a leap month before any one or two months of the year; when this happens, not only does the leap month take the name of the following month plus a special marker, the following month also takes a special marker. Moreover, in the Hindu calendar sometimes a month is skipped, in which case the preceding month takes a special marker plus the names of both months. The <monthPatterns> element structure supports these special kinds of month names. It parallels the <months> element structure, with various contexts and widths, but with some differences:

The Chinese and Hindu lunar calendars also use a 60-name cycle for designating years. The Chinese lunar calendars can also use that cycle for months and days, and can use 12-name cycles for designating day subdivisions or zodiac names associated with years; a 24-name cycle of solar terms (12 pairs of minor and major terms) is used to mark intervals in the solar cycle. The <cyclicNameSets> element structure supports these special kinds of name cycles; a cyclicNameSet can be provided for types "year", "month", "day", "dayParts", or "zodiacs". For each cyclicNameSet, there is a context and width structure similar to that for day names. For a given context and width, a set of cyclicName elements provides the actual names.

Example:

    <monthPatterns>
        <monthPatternContext type="format">
            <monthPatternWidth type="wide">
                <monthPattern type="leap">闰{0}</monthPattern>
            </monthPatternWidth>
        </monthPatternContext>
        <monthPatternContext type="stand-alone">
            <monthPatternWidth type="narrow">
                <monthPattern type="leap">闰{0}</monthPattern>
            </monthPatternWidth>
        </monthPatternContext>
        <monthPatternContext type="numeric">
            <monthPatternWidth type="all">
                <monthPattern type="leap">闰{0}</monthPattern>
            </monthPatternWidth>
        </monthPatternContext>
    </monthPatterns>
    <cyclicNameSets>
        <cyclicNameSet type="years">
            <cyclicNameContext type="format">
                <cyclicNameWidth type="abbreviated">
                    <cyclicName type="1">甲子</cyclicName>
                    <cyclicName type="2">乙丑</cyclicName>
                    ...
                    <cyclicName type="59">壬戌</cyclicName>
                    <cyclicName type="60">癸亥</cyclicName>
                </cyclicNameWidth>
            </cyclicNameContext>
        </cyclicNameSet>
        <cyclicNameSet type="zodiacs">
            <cyclicNameContext type="format">
                <cyclicNameWidth type="abbreviated">
                    <cyclicName type="1">鼠</cyclicName>
                    <cyclicName type="2">牛</cyclicName>
                    ...
                    <cyclicName type="11">狗</cyclicName>
                    <cyclicName type="12">猪</cyclicName>
                </cyclicNameWidth>
            </cyclicNameContext>
        </cyclicNameSet>
        <cyclicNameSet type="solarTerms">
            <cyclicNameContext type="format">
                <cyclicNameWidth type="abbreviated">
                    <cyclicName type="1">立春</cyclicName>
                    <cyclicName type="2">雨水</cyclicName>
                    ...
                    <cyclicName type="23">小寒</cyclicName>
                    <cyclicName type="24">大寒</cyclicName>
                </cyclicNameWidth>
            </cyclicNameContext>
        </cyclicNameSet>
    </cyclicNameSets>

2.3 Element dayPeriods

The former am/pm elements have been deprecated, and replaced by the more flexible dayPeriods.

<!ELEMENT dayPeriods ( alias | (dayPeriodContext*) ) >

<!ELEMENT dayPeriodContext (alias | dayPeriodWidth*) >
<!ATTLIST dayPeriodContext type NMTOKEN #REQUIRED >

<!ELEMENT dayPeriodWidth (alias | dayPeriod*) >
<!ATTLIST dayPeriodWidth type NMTOKEN #REQUIRED >

<!ELEMENT dayPeriod ( #PCDATA ) >
<!ATTLIST dayPeriod type NMTOKEN #REQUIRED >

These behave like months, days, and so on in terms of having context and width. Each locale has an associated dayPeriodRuleSet in the supplemental data, rules that specify when the day periods start and end for that locale. Each type in the rules needs to have a translation in a dayPeriod. For more information, see Day Period Rules.

The dayPeriod names should be distinct within each of the context/width combinations, including narrow; as with era names, there is less disambiguating information for them, and they are more likely to be used in a format that requires parsing. In some unambiguous cases, it is acceptable for certain overlapping dayPeriods to be the same, such as the names for "am" and "morning", or the names for "pm" and "afternoon".

Example:

    <dayPeriods>
      <dayPeriodContext type="format">
        <dayPeriodWidth type="wide">
          <dayPeriod type="am">AM</dayPeriod>
          <dayPeriod type="noon">noon</dayPeriod>
          <dayPeriod type="pm">PM</dayPeriod>
        </dayPeriodWidth>
      </dayPeriodContext>
    </dayPeriods>

2.4 Element dateFormats

<!ELEMENT dateFormats (alias | (default*, dateFormatLength*, special*)) >
<!ELEMENT dateFormatLength (alias | (default*, dateFormat*, special*)) >
<!ATTLIST dateFormatLength type ( full | long | medium | short ) #REQUIRED >
<!ELEMENT dateFormat (alias | (pattern*, displayName*, special*)) >

Standard date formats have the following form:

    <dateFormats>
      <dateFormatLength type=”full”>
        <dateFormat>
          <pattern>EEEE, MMMM d, y</pattern>
        </dateFormat>
      </dateFormatLength>
      <dateFormatLength type="medium">
        <dateFormat type="DateFormatsKey2">
          <pattern>MMM d, y</pattern>
        </dateFormat>
      </dateFormatLength>
    <dateFormats>

The patterns for date formats and time formats are defined in Date Format Patterns. These patterns are intended primarily for display of isolated date and time strings in user-interface elements, rather than for date and time strings in the middle of running text, so capitalization and grammatical form should be chosen appropriately.

Standard date and time patterns are each normally provided in four types: full (usually with weekday name), long (with wide month name), medium, and short (usually with numeric month).

2.5 Element timeFormats

<!ELEMENT timeFormats (alias | (default*, timeFormatLength*, special*)) >
<!ELEMENT timeFormatLength (alias | (default*, timeFormat*, special*)) >
<!ATTLIST timeFormatLength type ( full | long | medium | short ) #REQUIRED >
<!ELEMENT timeFormat (alias | (pattern*, displayName*, special*)) >

Standard time formats have the following form:

     <timeFormats>
       <timeFormatLength type=”full”>
         <timeFormat>
           <displayName>DIN 5008 (EN 28601)</displayName>
           <pattern>h:mm:ss a z</pattern>
         </timeFormat>
       </timeFormatLength>
       <timeFormatLength type="medium">
         <timeFormat>
           <pattern>h:mm:ss a</pattern>
         </timeFormat>
       </timeFormatLength>
     </timeFormats>

The preference of 12 hour versus 24 hour for the locale can be derived from the short timeFormat or from Time Data. If the hour symbol is "h" or "K" (of various lengths) then the format is 12 hour; otherwise it is 24 hour.

Time formats use the specific non-location format (z or zzzz) for the time zone name. This is the format that should be used when formatting a specific time for presentation. When formatting a time referring to a recurring time (such as a meeting in a calendar), applications should substitute the generic non-location format (v or vvvv) for the time zone in the time format pattern. See Using Time Zone Names. for a complete description of available time zone formats and their uses.

2.6 Element dateTimeFormats

<!ELEMENT dateTimeFormats (alias | (default*, dateTimeFormatLength*, availableFormats*, appendItems*, intervalFormats*, special*)) >

Date/Time formats have the following form:

     <dateTimeFormats>
       <dateTimeFormatLength type=”long”>
         <dateTimeFormat>
            <pattern>{1} 'at' {0}</pattern>
         </dateTimeFormat>
       </dateTimeFormatLength>
       <dateTimeFormatLength type=”medium”>
         <dateTimeFormat>
            <pattern>{1}, {0}</pattern>
         </dateTimeFormat>
       </dateTimeFormatLength>
       <availableFormats>
         <dateFormatItem id="Hm">HH:mm</dateFormatItem> 
         <dateFormatItem id="Hms">HH:mm:ss</dateFormatItem> 
         <dateFormatItem id="M">L</dateFormatItem> 
         <dateFormatItem id="MEd">E, M/d</dateFormatItem> 
         <dateFormatItem id="MMM">LLL</dateFormatItem> 
         <dateFormatItem id="MMMEd">E, MMM d</dateFormatItem> 
         <dateFormatItem id="MMMMEd">E, MMMM d</dateFormatItem> 
         <dateFormatItem id="MMMMd">MMMM d</dateFormatItem> 
         <dateFormatItem id="MMMd">MMM d</dateFormatItem> 
         <dateFormatItem id="Md">M/d</dateFormatItem> 
         <dateFormatItem id="d">d</dateFormatItem> 
         <dateFormatItem id="hm">h:mm a</dateFormatItem> 
         <dateFormatItem id="ms">mm:ss</dateFormatItem> 
         <dateFormatItem id="y">yyyy</dateFormatItem> 
         <dateFormatItem id="yM">M/yyyy</dateFormatItem> 
         <dateFormatItem id="yMEd">EEE, M/d/yyyy</dateFormatItem> 
         <dateFormatItem id="yMMM">MMM yyyy</dateFormatItem> 
         <dateFormatItem id="yMMMEd">EEE, MMM d, yyyy</dateFormatItem> 
         <dateFormatItem id="yMMMM">MMMM yyyy</dateFormatItem> 
         <dateFormatItem id="yQ">Q yyyy</dateFormatItem> 
         <dateFormatItem id="yQQQ">QQQ yyyy</dateFormatItem> 
         . . .
       </availableFormats>
       <appendItems>
         <appendItem request="G">{0} {1}</appendItem>
         <appendItem request="w">{0} ({2}: {1})</appendItem>
         . . .
       </appendItems>
     </dateTimeFormats>
  </calendar>

  <calendar type="buddhist">
    <eras>
      <eraAbbr>
        <era type="0">BE</era>
      </eraAbbr>
    </eras>
  </calendar>

These formats allow for date and time formats to be composed in various ways.

2.6.1 Element dateTimeFormat

<!ELEMENT dateTimeFormatLength (alias | (default*, dateTimeFormat*, special*))>
<!ATTLIST dateTimeFormatLength type ( full | long | medium | short ) #IMPLIED >
<!ELEMENT dateTimeFormat (alias | (pattern*, displayName*, special*))>

The dateTimeFormat element works like the dateFormats and timeFormats, except that the pattern is of the form "{1} {0}", where {0} is replaced by the time format, and {1} is replaced by the date format, with results such as "8/27/06 7:31 AM". Except for the substitution markers {0} and {1}, text in the dateTimeFormat is interpreted as part of a date/time pattern, and is subject to the same rules described in Date Format Patterns. This includes the need to enclose ASCII letters in single quotes if they are intended to represent literal text.

When combining a standard date pattern with a standard time pattern, the type of dateTimeFormat used to combine them is determined by the type of the date pattern. For example:

Date-Time Combination dateTimeFormat Results
full date + short time full, e.g. "{1} 'at' {0}" Wednesday, September 18, 2013 at 4:30 PM
medium date + long time medium, e.g. "{1}, {0}" Sep 18, 2013, 4:30:00 PM PDT

2.6.2 Elements availableFormats, appendItems

<!ELEMENT availableFormats (alias | (dateFormatItem*, special*))>
<!ELEMENT dateFormatItem ( #PCDATA ) >
<!ATTLIST dateFormatItem id CDATA #REQUIRED >

The availableFormats element and its subelements provide a more flexible formatting mechanism than the predefined list of patterns represented by dateFormatLength, timeFormatLength, and dateTimeFormatLength. Instead, there is an open-ended list of patterns (represented by dateFormatItem elements as well as the predefined patterns mentioned above) that can be matched against a requested set of calendar fields and field lengths. Software can look through the list and find the pattern that best matches the original request, based on the desired calendar fields and lengths. For example, the full month and year may be needed for a calendar application; the request is MMMMyyyy, but the best match may be "y MMMM" or even "G yy MMMM", depending on the locale and calendar.

For some calendars, such as Japanese, a displayed year must have an associated era, so for these calendars dateFormatItem patterns with a year field should also include an era field. When matching availableFormats patterns: If a client requests a format string containing a year, and all the availableFormats patterns with a year also contain an era, then include the era as part of the result.

The id attribute is a so-called "skeleton", containing only field information, and in a canonical order. Examples are "yMMMM" for year + full month, or "MMMd" for abbreviated month + day. In particular:

It is not necessary to supply dateFormatItems with skeletons for every field length; in many cases fields in the skeleton and pattern can be expanded in parallel to handle a request. Consider the following dateFormatItem:

    <dateFormatItem id="yMMMd">d MMM y</dateFormatItem>

If the request is for yMMMMd, the above item can be automatically expanded to produce the pattern "d MMMM y" in response to the request. Of course, if the desired behavior is that a request for yMMMMd should produce something other than "d MMMM y", a separate dateFormatItem must be added, for example:

    <dateFormatItem id="yMMMMd">d 'de' MMMM 'de' y</dateFormatItem>

In order to support user overrides of default locale behavior, data should be supplied for both 12-hour-cycle time formats (using h or K) and 24-hour-cycle time formats (using H or k), even if one of those styles is not commonly used; the locale's actual preference for 12-hour or 24-hour time cycle is determined from the hour character used in the locale's standard short time format. Thus skeletons using h or K should have patterns that only use h or K for hours, while skeletons using H or k should have patterns that only use H or k for hours.

If a client-requested set of fields includes both date and time fields, and if the availableFormats data does not include a dateFormatItem whose skeleton matches the same set of fields, then the request should be handled as follows:

  1. Divide the request into a date fields part and a time fields part
  2. For each part, find the matching dateFormatItem
  3. Combine the patterns for the two dateFormatItems using the appropriate dateTimeFormat pattern, determined as follows from the requested date fields:
    • If the requested date fields include wide month (MMMM, LLLL) and weekday name of any length (e.g. E, EEEE, c, cccc), use <dateTimeFormatLength type="full">
    • Otherwise, if the requested date fields include wide month, use <dateTimeFormatLength type="long">
    • Otherwise, if the requested date fields include abbreviated month (MMM, LLL), use <dateTimeFormatLength type="medium">
    • Otherwise use <dateTimeFormatLength type="short">

<!ELEMENT appendItems (alias | (appendItem*, special*))>
<!ELEMENT appendItem ( #PCDATA ) >
<!ATTLIST appendItem request CDATA >

In case the best match does not include all the requested calendar fields, the appendItems element describes how to append needed fields to one of the existing formats. Each appendItem element covers a single calendar field. In the pattern, {0} represents the format string, {1} the data content of the field, and {2} the display name of the field (see Calendar Fields).

2.6.3 Element intervalFormats

<!ELEMENT intervalFormats (alias | (intervalFormatFallback*, intervalFormatItem*, special*)) >

<!ELEMENT intervalFormatFallback ( #PCDATA ) >

<!ELEMENT intervalFormatItem (alias | (greatestDifference*, special*)) >
<!ATTLIST intervalFormatItem id NMTOKEN #REQUIRED >

<!ELEMENT greatestDifference ( #PCDATA ) >
<!ATTLIST greatestDifference id NMTOKEN #REQUIRED >

Interval formats allow for software to format intervals like "Jan 10-12, 2008" as a shorter and more natural format than "Jan 10, 2008 - Jan 12, 2008". They are designed to take a "skeleton" pattern (like the one used in availableFormats) plus start and end datetime, and use that information to produce a localized format.

The data supplied in CLDR requires the software to determine the calendar field with the greatest difference before using the format pattern. For example, the greatest difference in "Jan 10-12, 2008" is the day field, while the greatest difference in "Jan 10 - Feb 12, 2008" is the month field. This is used to pick the exact pattern. The pattern is then designed to be broken up into two pieces by determining the first repeating field. For example, "MMM d-d, y" would be broken up into "MMM d-" and "d, y". The two parts are formatted with the first and second datetime, as described in more detail below.

In case there is no matching pattern, the intervalFormatFallback defines the fallback pattern. The fallback pattern is of the form "{0} - {1}" or "{1} - {0}", where {0} is replaced by the start datetime, and {1} is replaced by the end datetime. The fallback pattern determines the default order of the interval pattern. "{0} - {1}" means the first part of the interval patterns in current local are formatted with the start datetime, while "{1} - {0}" means the first part of the interval patterns in current locale are formatted with the end datetime.

The id attribute of intervalFormatItem is the "skeleton" pattern (like the one used in availableFormats) on which the format pattern is based. The id attribute of greatestDifference is the calendar field letter, for example 'M', which is the greatest difference between start and end datetime.

The greatest difference defines a specific interval pattern of start and end datetime on a "skeleton" and a greatestDifference. As stated above, the interval pattern is designed to be broken up into two pieces. Each piece is similar to the pattern defined in date format. Also, each interval pattern could override the default order defined in fallback pattern. If an interval pattern starts with "latestFirst:", the first part of this particular interval pattern is formatted with the end datetime. If an interval pattern starts with "earliestFirst:", the first part of this particular interval pattern is formatted with the start datetime. Otherwise, the order is the same as the order defined in intervalFormatFallback.

For example, the English rules that produce "Jan 10–12, 2008", "Jan 10 – Feb 12, 2008", and "Jan 10, 2008 – Feb. 12, 2009" are as follows:

<intervalFormatItem id="yMMMd">
<greatestDifference id="M">MMM d – MMM d, yyyy</greatestDifference>
<greatestDifference id="d">MMM d–d, yyyy</greatestDifference>
<greatestDifference id="y">MMM d, yyyy – MMM d, yyyy</greatestDifference>
</intervalFormatItem>

To format a start and end datetime, given a particular "skeleton":

  1. Look for the intervalFormatItem element that matches the "skeleton", starting in the current locale and then following the locale fallback chain up to, but not including root (better results are obtained by following steps 2-6 below with locale- or language- specific data than by using matching intervalFormats from root).
  2. If no match was found from the previous step, check what the closest match is in the fallback locale chain, as in availableFormats. That is, this allows for adjusting the string value field's width, including adjusting between "MMM" and "MMMM", and using different variants of the same field, such as 'v' and 'z'.
  3. If a match is found from previous steps, compute the calendar field with the greatest difference between start and end datetime. If there is no difference among any of the fields in the pattern, format as a single date using availableFormats, and return.
  4. Otherwise, look for greatestDifference element that matches this particular greatest difference.
  5. If there is a match, use the pieces of the corresponding pattern to format the start and end datetime, as above.
  6. Otherwise, format the start and end datetime using the fallback pattern.

3 Calendar Fields

<!ELEMENT fields ( alias | (field*, special*)) >
<!ELEMENT field ( alias | (displayName*, relative*, relativeTime*, special*)) >
<!ATTLIST field type ( era | year | year-short | year-narrow | quarter | quarter-short | quarter-narrow | month | month-short | month-narrow | week | week-short | week-narrow | day | day-short | day-narrow | weekday | sun | sun-short | sun-narrow | mon | mon-short | mon-narrow | tue | tue-short | tue-narrow | wed | wed-short | wed-narrow | thu | thu-short | thu-narrow | fri | fri-short | fri-narrow | sat | sat-short | sat-narrow | dayperiod | hour | hour-short | hour-narrow | minute | minute-short | minute-narrow | second | second-short | second-narrow | zone ) #IMPLIED >

<!ELEMENT relative (#PCDATA) >
<!ATTLIST relative type NMTOKEN #IMPLIED >

<!ELEMENT relativeTime ( alias | (relativeTimePattern*, special*)) >
<!ATTLIST relativeTime type NMTOKEN #REQUIRED >

<!ELEMENT relativeTimePattern ( #PCDATA ) >
<!ATTLIST relativeTimePattern count ( zero | one | two | few | many | other ) #REQUIRED >

Translations may be supplied for names of calendar fields (elements of a calendar, such as Day, Month, Year, Hour, and so on), and for relative values for those fields (for example, the day with relative value -1 is "Yesterday"). There are three types of translations; some are only relevant or useful for certain types of fields:

Where there is not a convenient, customary word or phrase in a particular language for a particular type of relative value, it should be omitted.

Examples, first for English:

  <fields>
    …
    <field type="day">
      <displayName>Day</displayName>
      <relative type="-1">yesterday</relative>
      <relative type="0">today</relative>
      <relative type="1">tomorrow</relative>
      <relativeTime type="future">
        <relativeTimePattern count="one">in {0} day</relativeTimePattern>
        <relativeTimePattern count="other">in {0} days</relativeTimePattern>
      </relativeTime>
      <relativeTime type="past">
        <relativeTimePattern count="one">{0} day ago</relativeTimePattern>
        <relativeTimePattern count="other">{0} days ago</relativeTimePattern>
      </relativeTime>
    </field>
    <field type="weekday">
      <displayName>Day of the Week</displayName>
    </field>
    <field type="sun">
      <relative type="-1">last Sunday</relative>
      <relative type="0">this Sunday</relative>
      <relative type="1">next Sunday</relative>
    </field>
    …
    <field type="hour">
      <displayName>Hour</displayName>
      <relativeTime type="future">
        <relativeTimePattern count="one">in {0} hour</relativeTimePattern>
        <relativeTimePattern count="other">in {0} hours</relativeTimePattern>
      </relativeTime>
      <relativeTime type="past">
        <relativeTimePattern count="one">{0} hour ago</relativeTimePattern>
        <relativeTimePattern count="other">{0} hours ago</relativeTimePattern>
      </relativeTime>
    </field>
    …
  </fields>

Second, for German; includes relative type="-2"/"2", present in the English example:

  <fields>
    …
    <field type="day">
      <displayName>Tag</displayName>
      <relative type="-2">Vorgestern</relative>
      <relative type="-1">Gestern</relative>
      <relative type="0">Heute</relative>
      <relative type="1">Morgen</relative>
      <relative type="2">Übermorgen</relative>
      <relativeTime type="future">
        <relativeTimePattern count="one">In {0} Tag</relativeTimePattern>
        <relativeTimePattern count="other">In {0} Tagen</relativeTimePattern>
      </relativeTime>
      <relativeTime type="past">
        <relativeTimePattern count="one">Vor {0} Tag</relativeTimePattern>
        <relativeTimePattern count="other">Vor {0} Tagen</relativeTimePattern>
      </relativeTime>
    </field>
    …
  </fields>

A special name for “now” is indicated using <relative type="0"> for the "second" field. For example, in English:

    <field type="second">
      <displayName>Second</displayName>
      <relative type="0">now</relative>
      …
    </field>

Different widths can be supplied for certain fields, such as:

<field type="year-short">
<displayName>yr.</displayName>
<relative type="-1">last yr.</relative>
<relative type="0">this yr.</relative>
<relative type="1">next yr.</relative>
<relativeTime type="future">
<relativeTimePattern count="one">in {0} yr.</relativeTimePattern>
<relativeTimePattern count="other">in {0} yr.</relativeTimePattern>
</relativeTime>
<relativeTime type="past">
<relativeTimePattern count="one">{0} yr. ago</relativeTimePattern>
<relativeTimePattern count="other">{0} yr. ago</relativeTimePattern>
</relativeTime>
</field>

As in other cases, narrow may be ambiguous out of context.

4 Supplemental Calendar Data

4.1 Calendar Data

<!ELEMENT calendarData ( calendar* )>
<!ELEMENT calendar ( calendarSystem?, eras? )>
<!ATTLIST calendar type NMTOKENS #REQUIRED>
<!ATTLIST calendar territories NMTOKENS #IMPLIED > <!-- deprecated, replaced by calendarPreferenceData -->

<!ELEMENT calendarSystem EMPTY>
<!ATTLIST calendarSystem type (solar | lunar | lunisolar | other) #REQUIRED>

<!ELEMENT eras ( era* )>

<!ELEMENT era EMPTY>
<!ATTLIST era type NMTOKENS #REQUIRED>
<!ATTLIST era start CDATA #IMPLIED>
<!ATTLIST era end CDATA #IMPLIED>

The <calendarData> element now provides only locale-independent data about calendar behaviors via its <calendar> subelements, which for each calendar can specify the astronomical basis of the calendar (solar, lunar, etc.) and the date ranges for its eras.

Era start or end dates are specified in terms of the equivalent proleptic Gregorian date (in "y-M-d" format). Eras may be open-ended, with unspecified start or end dates. For example, here are the eras for the Gregorian calendar:

    <era type="0" end="0" />
    <era type="1" start="1" />

For a sequence of eras with specified start dates, the end of each era need not be explicitly specified (it is assumed to match the start of the subsequent era). For example, here are the first few eras for the Japanese calendar:

    <era type="0" start="645-6-19"/>
    <era type="1" start="650-2-15"/>
    <era type="2" start="672-1-1"/>
    …

Note: The territories attribute in the calendar element is deprecated. It was formerly used to indicate calendar preference by territory, but this is now given by the Calendar Preference Data below.

4.2 Calendar Preference Data

<!ELEMENT calendarPreferenceData ( calendarPreference* ) >
<!ELEMENT calendarPreference EMPTY >
<!ATTLIST calendarPreference territories NMTOKENS #REQUIRED >
<!ATTLIST calendarPreference ordering NMTOKENS #REQUIRED >

The calendarPreference element provides a list of commonly used calendar types in a territory. The ordering attribute indicates the list of calendar types in preferred order. The first calendar type in the list is the default calendar type for the territory. For example:

    <calendarPreference territories="001" ordering="gregorian"/>
    <calendarPreference territories="JP" ordering="gregorian japanese"/>
    <calendarPreference territories="TH" ordering="buddhist gregorian"/>

The calendarPreference elements above indicate:

The calendars in common use for a locale should typically be shown in UIs that provide a choice of calendars. (An 'Other...' button could give access to the other available calendars.)

4.3 Week Data

<!ELEMENT weekData ( minDays*, firstDay*, weekendStart*, weekendEnd* )>

<!ELEMENT minDays EMPTY>
<!ATTLIST minDays count (1 | 2 | 3 | 4 | 5 | 6 | 7) #REQUIRED>
<!ATTLIST minDays territories NMTOKENS #REQUIRED>

<!ELEMENT firstDay EMPTY >
<!ATTLIST firstDay day (sun | mon | tue | wed | thu | fri | sat) #REQUIRED>
<!ATTLIST firstDay territories NMTOKENS #REQUIRED>

<!ELEMENT weekendStart EMPTY>
<!ATTLIST weekendStart day (sun | mon | tue | wed | thu | fri | sat) #REQUIRED>
<!ATTLIST weekendStart territories NMTOKENS #REQUIRED>

<!ELEMENT weekendEnd EMPTY>
<!ATTLIST weekendEnd day (sun | mon | tue | wed | thu | fri | sat) #REQUIRED>
<!ATTLIST weekendEnd territories NMTOKENS #REQUIRED>

These values provide territory-specific information needed for week-of-year and week-of-month calculations, as well as information on conventions for first day of the week and for weekends. In each case, the default is provided by the element with territories="001".

<weekData>
  <minDays count="1" territories="001"/>
  <minDays count="4" territories="AD AN AT AX BE BG CH CZ DE DK EE ES FI FJ FO FR GB …"/>
  <firstDay day="mon" territories="001"/>
  <firstDay day="fri" territories="BD MV"/>
  <firstDay day="sat" territories="AE AF BH DJ DZ EG IQ IR JO …"/>
  …
  <weekendStart day="sat" territories="001"/>
  <weekendStart day="sun" territories="IN"/>
  <weekendStart day="thu" territories="AF DZ IR OM SA YE"/>
  <weekendStart day="fri" territories="AE BH EG IL IQ JO KW …"/>
  …

In order for a week to count as the first week of a new year for week-of-year calculations, it must include at least the number of days in the new year specified by the minDays value; otherwise the week will count as the last week of the previous year (and for week-of-month calculations, minDays also specifies the minimum number of days in the new month for a week to count as part of that month).

The day indicated by firstDay is the one that should be shown as the first day of the week in a calendar view. This is not necessarily the same as the first day after the weekend (or the first work day of the week), which should be determined from the weekend information. Currently, day-of-week numbering is based on firstDay (that is, day 1 is the day specified by firstDay), but in the future we may add a way to specify this separately.

What is meant by the weekend varies from country to country. It is typically when most non-retail businesses are closed. The time should not be specified unless it is a well-recognized part of the day. The weekendStart day defaults to "sat", and weekendEnd day defaults to "sun". For more information, see Dates and Date Ranges.

4.4 Time Data

<!ELEMENT timeData ( hours* ) >
<!ELEMENT hours EMPTY >
<!ATTLIST hours preferred NMTOKEN #REQUIRED >
<!ATTLIST hours allowed NMTOKENS #REQUIRED >
<!ATTLIST hours regions NMTOKENS #REQUIRED >

This element is for data that indicates, for various regions, the preferred time cycle in the region, as well as all time cycles that are considered acceptable in the region. The defaults are those specified for region 001.

There is a single preferred value, and multiple possible values. The meanings of the values H, h, K, k are defined in Date Field Symbol Table.

For example, in the following, RU (Russia) is marked as using only 24 hour time, and in particular the 24 hour time that goes from 0..23 (H), rather than from 1..24 (k).

<timeData>
    <hours preferred="H" allowed="H h" regions="001 …"/>
    <hours preferred="H" allowed="H K h" regions="JP"/>
    <hours preferred="H" allowed="H" regions="IL RU"/>
    <hours preferred="h" allowed="H h" regions="AE AG AL … US … ZW"/>
    …

4.5 Day Period Rules

<!ELEMENT dayPeriodRuleSet ( dayPeriodRules* ) >

<!ELEMENT dayPeriodRules (dayPeriodRule*) >
<!ATTLIST dayPeriodRules locales NMTOKENS #REQUIRED >

<!ELEMENT dayPeriodRule EMPTY >
<!ATTLIST dayPeriodRule type NMTOKEN #REQUIRED >
<!ATTLIST dayPeriodRule at NMTOKEN #IMPLIED >
<!ATTLIST dayPeriodRule after NMTOKEN #IMPLIED >
<!ATTLIST dayPeriodRule from NMTOKEN #IMPLIED >
<!ATTLIST dayPeriodRule before NMTOKEN #IMPLIED >
<!ATTLIST dayPeriodRule to NMTOKEN #IMPLIED >

Each locale should have a set of day period rules, which determine the periods during a day if used with a 12 hour format. If locales are not listed, dayPeriods fallback to AM/PM. Here are the requirements for a rule set:

  1. "from" and "to" are closed intervals (inclusive).
  2. "after" and "before" are open intervals (exclusive).
  3. "at" means starting time and end time are the same.
  4. There must be exactly one of {at, from, after} and exactly one of {at, to, before} for each dayPeriodRule.
  5. The set of dayPeriodRules need to completely cover the 24 hours in a day (from 0:00 before 24:00), with no overlaps between each dayPeriodRule.
  6. Both hh:mm [period name] and hh [period name] can be parsed uniquely to HH:mm [period name].
    1. For example, you can't have <dayPeriod type = "morning" from="0:00" to="12:00"/> because "12 {morning}" would be ambiguous.
  7. One dayPeriodRule can cross midnight. For example:
    1. <dayPeriodRule type="night" from="20:00" before="5:00"/>
    2. However, this should be avoided unless the alternative is awkward, because of ambiguities. While the use of the dayPeriods without hours is not recommended, they can be used. And if the user sees "Tuesday night" they may not think that that includes 1:00 am Tuesday.
  8. dayPeriodRules with the same type are only allowed if they are not adjacent. Example:
    • <dayPeriod type = "twilight" from="5:00" to="7:00"/>
    • <dayPeriod type = "twilight" from="17:00" to="19:00"/>
  9. 24:00 is only allowed in before="24:00". A term for midnight should be avoided in the rules, because of ambiguity problems in most languages.
    1. "Tuesday midnight" generally means at the end of the day on Tuesday (24:00)
    2. Most software does not format anything for 24:00, only for 00:00. And you don't want 00:00 Tuesday (the start of the day) to be formatted as midnight, meaning the end of the day.
  10. When parsing, if the hour is present the dayperiod is checked for consistency. If there is no hour, the center of the first matching dayPeriodRule is chosen (starting from 0:00).
  11. If rounding is done—including the rounding done by the time format—then it needs to be done before the dayperiod is computed, so that the correct format is shown.

5 Time Zone Names

<!ELEMENT timeZoneNames (alias | (hourFormat*, gmtFormat*, gmtZeroFormat*, regionFormat*, fallbackFormat*, zone*, metazone*, special*)) >

<!ELEMENT hourFormat ( #PCDATA ) >
<!ELEMENT gmtFormat ( #PCDATA ) >
<!ELEMENT gmtZeroFormat ( #PCDATA ) >

<!ELEMENT regionFormat ( #PCDATA ) >
<!ATTLIST regionFormat type ( standard | daylight ) #IMPLIED >

<!ELEMENT fallbackFormat ( #PCDATA ) >

<!ELEMENT zone (alias | ( long*, short*, exemplarCity*, special*)) >
<!ATTLIST zone type CDATA #REQUIRED >

<!ELEMENT metazone (alias | ( long*, short*, special*)) >
<!ATTLIST metazone type CDATA #REQUIRED >

<!ELEMENT long (alias | (generic*, standard*, daylight*, special*)) >
<!ELEMENT short (alias | (generic*, standard*, daylight*, special*)) >

<!ELEMENT generic ( #PCDATA ) >
<!ELEMENT standard ( #PCDATA ) >
<!ELEMENT daylight ( #PCDATA ) >

<!ELEMENT exemplarCity ( #PCDATA ) >

The time zone IDs (tzid) are language-independent, and follow the TZ time zone database [Olson] and naming conventions. However, the display names for those IDs can vary by locale. The generic time is so-called wall-time; what clocks use when they are correctly switched from standard to daylight time at the mandated time of the year.

Unfortunately, the canonical tzid's (those in zone.tab) are not stable: may change in each release of the TZ Time Zone database. In CLDR, however, stability of identifiers is very important. So the canonical IDs in CLDR are kept stable as described in Canonical Form.

The TZ time zone database can have multiple IDs that refer to the same entity. It does contain information on equivalence relationships between these IDs, such as "Asia/Calcutta" and "Asia/Kolkata". It does not remove IDs (with a few known exceptions), but it may change the "canonical" ID which is in the file zone.tab.

For lookup purposes specifications such as CLDR need a stable canonical ID, one that does not change from release to release. The stable ID is maintained as the first alias item type element in the file bcp47/timezone.xml, such as:

<type name="inccu" alias="Asia/Calcutta Asia/Kolkata"/>

That file also contains the short ID used in keywords. In versions of CLDR previous to 1.8, the alias information (but not the short ID) was in Supplemental Data under the zoneItem, such as:

<zoneItem type="Asia/Calcutta" territory="IN" aliases="Asia/Kolkata"/>

This element was deprecated after the introduction of bcp47/timezone.xml, because the information became redundant (or was contained in the TZ time zone database).

The following is an example of time zone data. Although this is an example of possible data, in most cases only the exemplarCity needs translation. And that does not even need to be present, if a country only has a single time one. As always, the type field for each zone is the identification of that zone. It is not to be translated.

<zone type="America/Los_Angeles">
    <long>
        <generic>Pacific Time</generic>
        <standard>Pacific Standard Time</standard>
        <daylight>Pacific Daylight Time</daylight>
    </long>
    <short>
        <generic>PT</generic>
        <standard>PST</standard>
        <daylight>PDT</daylight>
    </short>
    <exemplarCity>San Francisco</exemplarCity>
</zone>

<zone type="Europe/London">
     <long>
        <generic>British Time</generic>
        <standard>British Standard Time</standard>
        <daylight>British Daylight Time</daylight>
    </long>
    <exemplarCity>York</exemplarCity>
</zone>\

In a few cases, some time zone IDs do not designate a city, as in:

<zone type="America/Puerto_Rico">
    ...
</zone>

<zone type="America/Guyana">
    ...
</zone>

<zone type="America/Cayman">
    ...
</zone>

<zone type="America/St_Vincent">
    ...
</zone>

They may designate countries or territories; their actual capital city may be a name that is too common, or, too uncommon. CLDR time zone IDs follow the Olson naming conventions.

Note: CLDR does not allow "GMT", "UT", or "UTC" as translations (short or long) of time zones other than GMT itself.

Note: Transmitting "14:30" with no other context is incomplete unless it contains information about the time zone. Ideally one would transmit neutral-format date/time information, commonly in UTC (GMT), and localize as close to the user as possible. (For more about UTC, see [UTCInfo].)

The conversion from local time into UTC depends on the particular time zone rules, which will vary by location. The standard data used for converting local time (sometimes called wall time) to UTC and back is the TZ Data [Olson], used by Linux, UNIX, Java, ICU, and others. The data includes rules for matching the laws for time changes in different countries. For example, for the US it is:

"During the period commencing at 2 o'clock antemeridian on the second Sunday of March of each year and ending at 2 o'clock antemeridian on the first Sunday of November of each year, the standard time of each zone established by sections 261 to 264 of this title, as modified by section 265 of this title, shall be advanced one hour..." (United States Law - 15 U.S.C. §6(IX)(260-7), as amended by Energy Policy Act of 2005).

Each region that has a different time zone or daylight savings time rules, either now or at any time back to 1970, is given a unique internal ID, such as Europe/Paris . (Some IDs are also distinguished on the basis of differences before 1970.) As with currency codes, these are internal codes. A localized string associated with these is provided for users (such as in the Windows Control Panels>Date/Time>Time Zone).

Unfortunately, laws change over time, and will continue to change in the future, both for the boundaries of time zone regions and the rules for daylight savings. Thus the TZ data is continually being augmented. Any two implementations using the same version of the TZ data will get the same results for the same IDs (assuming a correct implementation). However, if implementations use different versions of the data they may get different results. So if precise results are required then both the TZ ID and the TZ data version must be transmitted between the different implementations.

For more information, see [Data Formats].

The following subelements of time zoneNames are used to control the fallback process described in Using Time Zone Names.

Element Name Data Examples Results/Comment
hourFormat "+HHmm;-HHmm" "+1200"
"-1200"
gmtFormat "GMT{0}" "GMT-0800"
"{0}ВпГ" "-0800ВпГ"
gmtZeroFormat "GMT" Specifies how GMT/UTC with no explicit offset (implied 0 offset) should be represented.
regionFormat "{0} Time" "Japan Time"
"Hora de {0}" "Hora de Japón"
regionFormat type="daylight"
(or "standard")
"{0} Daylight Time" "France Daylight Time"
"horario de verano de {0}" "horario de verano de Francia"
fallbackFormat "{1} ({0})" "Pacific Time (Canada)"

When referring to the abbreviated (short) form of the time zone name, there are often situations where the location-based (city or country) time zone designation for a particular language may not be in common usage in a particular territory.

Note: User interfaces for time zone selection can use the "generic location format" for time zone names to obtain the most useful ordering of names in a menu or list; see Using Time Zone Names and the zone section of the Date Field Symbol Table.

5.1 Metazone Names

A metazone is an grouping of one or more internal TZIDs that share a common display name in current customary usage, or that have shared a common display name during some particular time period. For example, the zones Europe/Paris, Europe/Andorra, Europe/Tirane, Europe/Vienna, Europe/Sarajevo, Europe/Brussels, Europe/Zurich, Europe/Prague, Europe/Berlin, and so on are often simply designated Central European Time (or translated equivalent).

A metazone's display fields become a secondary fallback if an appropriate data field cannot be found in the explicit time zone data. The usesMetazone field indicates that the target metazone is active for a particular time. This also provides a mechanism to effectively deal with situations where the time zone in use has changed for some reason. For example, consider the TZID "America/Indiana/Knox", which observed Central time (GMT-6:00) prior to October 27, 1991, and has currently observed Central time since April 2, 2006, but has observed Eastern time ( GMT-5:00 ) between these two dates. This is denoted as follows

<timezone type="America/Indiana/Knox">
  <usesMetazone to="1991-10-27 07:00" mzone="America_Central"/>
  <usesMetazone to="2006-04-02 07:00" from="1991-10-27 07:00" mzone="America_Eastern"/>
  <usesMetazone from="2006-04-02 07:00" mzone="America_Central"/>
</timezone>

Note that the dates and times are specified in UTC, not local time.

The metazones can then have translations in different locale files, such as the following.

<metazone type="America_Central"> 
  <long> 
    <generic>Central Time</generic> 
    <standard>Central Standard Time</standard> 
    <daylight>Central Daylight Time</daylight> 
  </long> 
  <short> 
    <generic>CT</generic> 
    <standard>CST</standard> 
    <daylight>CDT</daylight> 
  </short> 
</metazone> 
<metazone type="America_Eastern"> 
  <long> 
    <generic>Eastern Time</generic> 
    <standard>Eastern Standard Time</standard> 
    <daylight>Eastern Daylight Time</daylight> 
  </long> 
  <short> 
    <generic>ET</generic> 
    <standard>EST</standard> 
    <daylight>EDT</daylight> 
  </short> 
</metazone>
<metazone type="America_Eastern">
  <long>
    <generic>Heure de l’Est</generic>
    <standard>Heure normale de l’Est</standard>
    <daylight>Heure avancée de l’Est</daylight>
  </long>
  <short>
    <generic>HE</generic>
    <standard>HNE</standard>
    <daylight>HAE</daylight>
  </short>
</metazone>

When formatting a date and time value using this data, an application can properly be able to display "Eastern Time" for dates between 1991-10-27 and 2006-04-02, but display "Central Time" for current dates. (See also Dates and Date Ranges).

Metazones are used with the 'z', 'zzzz', 'v', and 'vvvv date time pattern characters, and not with the 'Z', 'ZZZZ', 'VVVV' and other pattern characters for time zone formatting. For more information, see Date Format Patterns .

The commonlyUsed element is now deprecated. The CLDR committee has found it nearly impossible to obtain accurate and reliable data regarding which time zone abbreviations may be understood in a given territory, and therefore has changed to a simpler approach. Thus, if the short metazone form is available in a given locale, it is to be used for formatting regardless of the value of commonlyUsed. If a given short metazone form is known NOT to be understood in a given locale and the parent locale has this value such that it would normally be inherited, the inheritance of this value can be explicitly disabled by use of the 'no inheritance marker' as the value, which is 3 simultaneous empty set characters ( U+2205 ).

6 Supplemental Time Zone Data

6.1 Metazones

<!ELEMENT metaZones (metazoneInfo?, mapTimezones?) >

<!ELEMENT metazoneInfo (timezone*) >

<!ELEMENT timezone (usesMetazone*) >
<!ATTLIST timezone type CDATA #REQUIRED >

<!ELEMENT usesMetazone EMPTY >
<!ATTLIST usesMetazone mzone NMTOKEN #REQUIRED >
<!ATTLIST usesMetazone from CDATA #IMPLIED >
<!ATTLIST usesMetazone to CDATA #IMPLIED >

<!ELEMENT mapTimezones ( mapZone* ) >
<!ATTLIST mapTimezones type NMTOKEN #IMPLIED >
<!ATTLIST mapTimezones typeVersion CDATA #IMPLIED >
<!ATTLIST mapTimezones otherVersion CDATA #IMPLIED >
<!ATTLIST mapTimezones references CDATA #IMPLIED >

<!ELEMENT mapZone EMPTY >
<!ATTLIST mapZone type CDATA #REQUIRED >
<!ATTLIST mapZone other CDATA #REQUIRED >
<!ATTLIST mapZone territory CDATA #IMPLIED >
<!ATTLIST mapZone references CDATA #IMPLIED >

The following subelement of <metaZones> provides a mapping from a single Unicode time zone id to metazones. For more information about metazones, See Time Zone Names.

<metazoneInfo>
	<timezone type="Europe/Andorra">
		<usesMetazone mzone="Europe_Central"/>
	</timezone>
	....
	<timezone type="Asia/Yerevan">
		<usesMetazone to="1991-09-22 20:00" mzone="Yerevan"/>
		<usesMetazone from="1991-09-22 20:00" mzone="Armenia"/>
	</timezone>
	....

The following subelement of <metaZones> specifies a mapping from a metazone to golden zones for each territory. For more information about golden zones, see Using Time Zone Names.

<mapTimezones type="metazones">
	<mapZone other="Acre" territory="001" type="America/Rio_Branco"/>
	<mapZone other="Afghanistan" territory="001" type="Asia/Kabul"/>
	<mapZone other="Africa_Central" territory="001" type="Africa/Maputo"/>
	<mapZone other="Africa_Central" territory="BI" type="Africa/Bujumbura"/>
	<mapZone other="Africa_Central" territory="BW" type="Africa/Gaborone"/>
	....

6.2 Windows Zones

<!ELEMENT windowsZones (mapTimezones?) >

The <mapTimezones> element can be also used to provide mappings between Unicode time zone IDs and other time zone IDs. This example specifies a mapping from Windows TZIDs to Unicode time zone IDs .

<mapTimezones otherVersion="07dc0000" typeVersion="2011n">
	....
	<!-- (UTC-08:00) Baja California -->
	<mapZone other="Pacific Standard Time (Mexico)" territory="001" type="America/Santa_Isabel"/>
	<mapZone other="Pacific Standard Time (Mexico)" territory="MX" type="America/Santa_Isabel"/>

	<!-- (UTC-08:00) Pacific Time (US & Canada) -->
	<mapZone other="Pacific Standard Time" territory="001" type="America/Los_Angeles"/>
	<mapZone other="Pacific Standard Time" territory="CA" type="America/Vancouver America/Dawson America/Whitehorse"/>
	<mapZone other="Pacific Standard Time" territory="MX" type="America/Tijuana"/>
	<mapZone other="Pacific Standard Time" territory="US" type="America/Los_Angeles"/>
	<mapZone other="Pacific Standard Time" territory="ZZ" type="PST8PDT"/>
	....

The attributes otherVersion and typeVersion in <mapTimezones> specify the versions of two systems. In the example above, otherVersion="07dc0000" specifies the version of Windows time zone and typeVersion="2011n" specifies the version of Unicode time zone IDs. The attribute territory="001" in <mapZone> element indicates the long canonical Unicode time zone ID specified by the type attribute is used as the default mapping for the Windows TZID. For each unique Windows TZID, there must be exactly one <mapZone> element with territory="001". <mapZone> elements other than territory="001" specify territory specific mappings. When multiple Unicode time zone IDs are available for a single territory, the value of the type attribute will be a list of Unicode time zone IDs delimited by space. In this case, the first entry represents the default mapping for the territory. The territory "ZZ" is used when a Unicode time zone ID is not associated with a specific territory.

Note: The long canonical Unicode time zone ID might be deprecated in the tz database[Olson]. For example, CLDR uses "Asia/Culcutta" as the long canonical time zone ID for Kolkata, India. The same ID was moved to 'backward' file and replaced with a new ID "Asia/Kolkata" in the tz database. Therefore, if you want to get an equivalent Windows TZID for a zone ID in the tz dadtabase, you have to resolve the long canonical Unicode time zone ID (e.g. "Asia/Culcutta") for the zone ID (e.g. "Asia/Kolkata"). For more details, see Section 3.7.1.2 Time Zone Identifiers.

Note: Not all Unicode time zones have equivalent Windows TZID mappings. Also, not all Windows TZIDs have equivalent Unicode time zones. For example, there is no equivalent Windows zone for Unicode time zone "Australia/Lord_Howe", and there is no equivalent Unicode time zone for Windows zone "E. Europe Standard Time" (as of CLDR 25 release).

6.3 Primary Zones

<!ELEMENT primaryZones ( primaryZone* ) >
<!ELEMENT primaryZone ( #PCDATA ) >
<!ATTLIST primaryZone iso3166 NMTOKEN #REQUIRED >

This element is for data that is used to format a time zone’s generic location name. Each <primaryZone> element specifies the dominant zone for a region; this zone should use the region name for its generic location name even though there are other canonical zones available in the same region. For example, Asia/Shanghai is displayed as "China Time", instead of "Shanghai Time". Sample data:

<primaryZones>
    <primaryZone iso3166="CL">America/Santiago</primaryZone>
    <primaryZone iso3166="CN">Asia/Shanghai</primaryZone>
    <primaryZone iso3166="DE">Europe/Berlin</primaryZone>
    …

This information was previously specified by the LDML <singleCountries> element under each locale’s <timeZoneNames> element. However, that approach had inheritance issues, and the data is not really locale-specific anyway.

7 Using Time Zone Names

There are three main types of formats for zone identifiers: GMT, generic (wall time), and standard/daylight. Standard and daylight are equivalent to a particular offset from GMT, and can be represented by a GMT offset as a fallback. In general, this is not true for the generic format, which is used for picking timezones or for conveying a timezone for specifying a recurring time (such as a meeting in a calendar). For either purpose, a GMT offset would lose information.

7.1 Time Zone Format Terminology

The following terminology defines more precisely the formats that are used.

Generic non-location format: Reflects "wall time" (what is on a clock on the wall): used for recurring events, meetings, or anywhere people do not want to be overly specific. For example, "10 am Pacific Time" will be GMT-8 in the winter, and GMT-7 in the summer.

Generic partial location format: Reflects "wall time": used as a fallback format when the generic non-location format is not specific enough.

Generic location format: Reflects "wall time": a primary function of this format type is to represent a time zone in a list or menu for user selection of time zone, since the naming is more uniform than the generic non-location format and zones for the same country will be grouped together (and could be organized hierarchically by country if desired). It is also a fallback format when there is no translation for the generic non-location format.

Note: A generic location format is constructed by a part of time zone ID representing an exemplar city name or its country as the final fallback. However, there are Unicode time zones which are not associated with any locations, such as "Etc/GMT+5" and "PST8PDT". The date format pattern "vvvv" specifies the generic location format, but it displays localized GMT format for them. Some of these time zones observe daylight saving time, so the result (localized GMT format) may change depending on input date. For generating a list for user selection of time zone with format "vvvv", these non-location zones should be excluded.

Specific non-location format: Reflects a specific standard or daylight time, which may or may not be the wall time. For example, "10 am Pacific Standard Time" will be GMT-8 in the winter and in the summer.

Localized GMT format: A constant, specific offset from GMT (or UTC), which may be in a translated form. There are two styles for this. The first is used when there is an explicit non-zero offset from GMT; this style is specified by the <gmtFormat> element and <hourFormat> element. The long format always uses 2-digit hours field and minutes field, with optional 2-digit seconds field. The short format is intended for the shortest representation and uses hour fields without leading zero, with optional 2-digit minutes and seconds fields. The digits used for hours, minutes and seconds fields in this format are the locale's default decimal digits:

Otherwise (when the offset from GMT is zero, referring to GMT itself) the style specified by the <gmtZeroFormat> element is used:

ISO 8601 time zone formats: The formats based on the ISO 8601 local time difference from UTC, or the UTC indicator ("Z" - only when the local time offset is 0 and the specifier X* is used). The ISO 8601 basic format does not use a separator character between hours and minutes field, while the extended format uses colon (':') as the separator. The ISO 8601 basic format with hours and minutes fields is equivalent to RFC 822 zone format.

Note: This specification extends the original ISO 8601 formats and some format specifiers append seconds field when necessary.

Raw Offset - an offset from GMT that does not include any daylight savings behavior. For example, the raw offset for Pacific Time is -8, even though the observed offset may be -8 or -7.

Metazone - a collection of time zones that share the same behavior and same name during some period. They may differ in daylight behavior (whether they have it and when).

For example, the TZID America/Cambridge_Bay is in the following metazones during various periods:

<timezone type="America/Cambridge_Bay">
<usesMetazone to="1999-10-31 08:00" mzone="America_Mountain"/>
<usesMetazone to="2000-10-29 07:00" from="1999-10-31 08:00" mzone="America_Central"/>
<usesMetazone to="2000-11-05 05:00" from="2000-10-29 07:00" mzone="America_Eastern"/>
<usesMetazone to="2001-04-01 09:00" from="2000-11-05 05:00" mzone="America_Central"/>
<usesMetazone from="2001-04-01 09:00" mzone="America_Mountain"/>
</timezone>

Zones may join or leave a metazone over time. The data relating between zones and metazones is in the supplemental information; the locale data is restricted to translations of metazones and zones.

Invariants:

Golden Zone - the TZDB zone that exemplifies a metazone. For example, America/New_York is the golden zone for the metazone America_Eastern:

<mapZone other="America_Eastern" territory="001" type="America/New_York"/>

Invariants:

Preferred Zone - for a given TZID, the "best" zone out of a metazone for a given country or language.

Invariants:

For example, for America_Pacific the preferred zone for Canada is America/Vancouver, and the preferred zone for Mexico is America/Tijuana. The golden zone is America/Los_Angeles, which is also also the preferred zone for any other country.

<mapZone other="America_Pacific" territory="001" type="America/Los_Angeles"/>
<mapZone other="America_Pacific" territory="CA" type="America/Vancouver"/>
<mapZone other="America_Pacific" territory="MX" type="America/Tijuana"/>

fallbackFormat: a formatting string such as "{1} ({0})", where {1} is the metazone, and {0} is the country or city.

regionFormat: a formatting string such as "{0} Time", where {0} is the country or city.

7.2 Goals

The timezones are designed so that:

For any given locale, every time round trips with all patterns (but not necessarily every timezone). That is, given a time and a format pattern with a zone string, you can format, then parse, and get back the same time.

Note that the round-tripping is not just important for parsing; it provides for formatting dates and times in an unambiguous way for users. It is also important for testing.

There are exceptions to the above for transition times.

The V/VV/VVV/VVVV format will roundtrip not only the time, but the canonical timezone.

When the data for a given format is not available, a fallback format is used. The fallback order is given in the following by a list.

  1. Specifics
    • z - [short form] specific non-location
      • falling back to short localized GMT
    • zzzz - [long form] specific non-location
      • falling back to long localized GMT
    • Z/ZZZZZ/X+/x+ - ISO 8601 formats (no fallback necessary)
    • ZZZZ/O+ - Localized GMT formats (no fallback necessary)
  2. Generics
    • v - [short form] generic non-location
      (however, the rules are more complicated, see #5 below)
      • falling back to generic location
      • falling back to short localized GMT
    • vvvv - [long form] generic non-location
      (however, the rules are more complicated, see #5 below)
      • falling back to generic location
      • falling back to long localized GMT
    • V - short time zone ID
      • falling back to the special ID "unk" (Unknown)
    • VV - long time zone ID (no fallback necessary, because this is the input)
    • VVV - exemplar city
      • falling back to the localized exemplar city for the unknown zone (Etc/Unknown), for example "Unknown City" for English
    • VVVV - generic location
      • falling back to long localized GMT

The following process is used for the particular formats, with the fallback rules as above.

Some of the examples are drawn from real data, while others are for illustration. For illustration the region format is "Hora de {0}". The fallback format in the examples is "{1} ({0})", which is what is in root.

  1. In all cases, first canonicalize the TZ ID according to the Unicode Locale Extension type mapping data (See Time Zone Identifiers for more details).. Use that canonical TZID in each of the following steps.
    • America/Atka → America/Adak
    • Australia/ACT → Australia/Sydney
  2. For the localized GMT format, use the gmtFormat (such as "GMT{0}" or "HMG{0}") with the hourFormat (such as "+HH:mm;-HH:mm" or "+HH.mm;-HH.mm").
    • America/Los_Angeles → "GMT-08:00" // standard time
    • America/Los_Angeles → "HMG-07:00" // daylight time
    • Etc/GMT+3 → "GMT-03.00" // note that TZ tzids have inverse polarity!

    Note: The digits should be whatever are appropriate for the locale used to format the time zone, not necessarily from the western digits, 0..9. For example, they might be from ०..९.

  3. For ISO 8601 time zone format return the results according to the ISO 8601 specification.
    • America/Los_Angeles →
      • "-08" ("X","x")
      • "-0800" ("Z","XX","XXXX","xx","xxxx")
      • "-08:00" ("ZZZZZ","XXX","XXXXX","xxx","xxxxx")
    • Etc/GMT →
      • "Z" ("ZZZZZ", "X", "XX", "XXX", "XXXX", "XXXXX")
      • "+00" ("x")
      • "+0000" ("Z", "xx", "xxxx")
      • "+00:00" ("xxx", "xxxxx")

    Note: The digits in this case are always from the western digits, 0..9.

  4. For the non-location formats (generic or specific):
    1. if there is an explicit translation for the TZID in <timeZoneNames> according to type (generic, standard, or daylight) in the resolved locale, return it.
      1. If the requested type is not available, but another type is, and there is a Type Fallback then return that other type.
        • Examples:
          • America/Los_Angeles → // generic
          • America/Los_Angeles → "アメリカ太平洋標準時" // standard
          • America/Los_Angeles → "Yhdysvaltain Tyynenmeren kesäaika" // daylight
          • Europe/Dublin  → "Am Samhraidh na hÉireann" // daylight
          • Note: This translation may not at all be literal: it would be what is most recognizable for people using the target language.
    2. Otherwise, get the requested metazone format according to type (generic, standard, daylight).
      1. If the requested type is not available, but another type is, get the format according to Type Fallback.
      2. If there is no format for the type, fall back.
    3. Otherwise do the following:
      1. Get the country for the current locale. If there is none, use the most likely country based on the likelySubtags data. If there is none, use “001”.
      2. Get the preferred zone for the metazone for the country; if there is none for the country, use the preferred zone for the metazone for “001”.
      3. If that preferred zone is the same as the requested zone, use the metazone format. For example, "Pacific Time" for Vancouver if the locale is en_CA, or for Los Angeles if locale is en_US.
      4. Otherwise, if the zone is the preferred zone for its country but not for the country of the locale, use the metazone format + country in the fallbackFormat.
      5. Otherwise, use the metazone format + city in the fallbackFormat.
        • Examples:
          • "Pacific Time (Canada)" // for the zone Vancouver in the locale en_MX.
          • "Mountain Time (Phoenix)"
          • "Pacific Time (Whitehorse)"
  5. For the generic location format:
    1. From the TZDB get the country code for the zone, and determine whether there is only one timezone in the country. If there is only one timezone or if the zone id is in the <primaryZones> list, format the country name with the regionFormat, and return it.
      • Examples:
        • Europe/Rome → IT → "Italy Time" // for English
        • Asia/Shanghai → CN → "China Time" // Asia/Shanghai is the primaryZone for China
        • Africa/Monrovia → LR → "Hora de Liberja"
        • America/Havana → CU → "Hora de CU" // if CU is not localized
    2. Otherwise format the exemplar city with the regionFormat, and return it.
      1. America/Buenos_Aires → "Buenos Aires Time"

Note: If a language does require grammatical changes when composing strings, then the regionFormat should either use a neutral format such as "Heure: {0}", or put all exceptional cases in explicitly translated strings.

Type Fallback

When a specified type (generic, standard, daylight) does not exist:

  1. If the daylight type does not exist, then the metazone doesn’t require daylight support. For all three types:
    1. If the generic type exists, use it.
    2. Otherwise if the standard type exists, use it.
  2. Otherwise if the generic type is needed, but not available, and the offset and daylight offset do not change within 184 day +/- interval around the exact formatted time, use the standard type.
    1. Example: "Mountain Standard Time" for Phoenix
    2. Note: 184 is the smallest number that is at least 6 months AND the smallest number that is more than 1/2 year (Gregorian).

Composition

In composing the metazone + city or country:

  1. Use the fallbackFormat "{1} ({0})", where:
    • {1} will be the metazone
    • {0} will be a qualifier (city or country)
    • Example:
      • metazone = Pacific Time
      • city = Phoenix
      • → "Pacific Time (Phoenix)"
  2. If the localized country name is not available, use the code:
    • CU (country code)→ "CU" // no localized country name for Cuba
  3. If the localized exemplar city is not available, use as the exemplar city the last field of the raw TZID, stripping off the prefix and turning _ into space.
    • America/Los_Angeles → "Los Angeles" // no localized exemplar city

Note: As with the regionFormat, exceptional cases need to be explicitly translated.

7.3 Parsing

In parsing, an implementation will be able to either determine the zone id, or a simple offset from GMT for anything formatting according to the above process.

The following is a sample process for how this might be done. It is only a sample; implementations may use different methods for parsing.

The sample describes the parsing of a zone as if it were an isolated string. In implementations, the zone may be mixed in with other data (like the time), so the parsing actually has to look for the longest match, and then allow the remaining text to be parsed for other content. That requires certain adaptions to the following process.

  1. Start with a string S.
  2. If S matches ISO 8601 time zone format, return it.
    • For example, "-0800" (RFC 822), "-08:00" (ISO 8601) => Etc/GMT+8
  3. If S matches the English or localized GMT format, return the corresponding TZID
    • Matching should be lenient. Thus allow for the number formats like: 03, 3, 330, 3:30, 33045 or 3:30:45. Allow +, -, or nothing. Allow spaces after GMT, +/-, and before number. Allow non-Latin numbers. Allow UTC or UT (per RFC 788) as synonyms for GMT ("GMT", "UT", "UTC" are global formats, always allowed in parsing regardless of locale).
    • For example, "GMT+3" or "UT+3" or "HPG+3" => Etc/GMT-3
    • When parsing, the absence of a numeric offset should be interpreted as offset 0, whether in localized or global formats. For example, "GMT" or "UT" or "UTC+0" or "HPG" => Etc/GMT
  4. If S matches the fallback format, extract P = {0} [ie, the part in parens in the root format] and N = {1}.
    If S does not match, set P = "" and N = S
    If N matches the region format, then M = {0} from that format, otherwise M = N.
    • For example, "United States (Los Angeles) Time" => N = "United States Time", M = "United States", P = "Los Angeles".
    • For example, "United States Time" => N = "United States Time", M = "United States", P = "".
    • For example, "United States" => N = M = "United States", P = "".
  5. If P, N, or M is a localized country, set C to that value. If C has only one zone, return it.
    • For example, "Italy Time (xxx)" or "xxx (Italy)" => Europe/Rome
    • For example, "xxx (Canada)" or "Canada Time (xxx)" => Sets C = CA and continues
  6. If P is a localized exemplar city name (and not metazone), return it.
    • For example, "xxxx (Phoenix)" or "Phoenix (xxx)" => America/Phoenix
  7. If N, or M is a localized time zone name (and not metazone), return it.
    • For example, "Pacific Standard Time (xxx)" => "America/Los_Angeles" // this is only if "Pacific Standard Time" is not a metazone localization.
  8. If N or M is a localized metazone
    • If it corresponds to only one TZID, return it.
    • If C is set, look up the Metazone + Country => TZID mapping, and return that value if it exists
    • Get the locale's language, and get the default country from that. Look up the Metazone + DefaultCountry => TZID mapping, and return that value if it exists.
    • Otherwise, lookup Metazone + 001 => TZID and return it (that will always exist)
  9. If you get this far, return an error.

Note: This CLDR date parsing recommendation does not fully handle all RFC 788 date/time formats, nor is it intended to.

Parsing can be more lenient than the above, allowing for different spacing, punctuation, or other variation. A stricter parse would check for consistency between the xxx portions above and the rest, so "Pacific Standard Time (India)" would give an error.

Using this process, a correct parse will roundtrip the location format (VVVV) back to the canonical zoneid.

The GMT formats (Z and ZZZZ) will return back an offset, and thus lose the original canonical zone id.

The daylight and standard time formats, and the non-location formats (z, zzzz, v, and vvvv) may either roundtrip back to the original canonical zone id, to a zone in the same metazone that time, or to just an offset, depending on the available translation data. Thus:

8 Date Format Patterns

A date pattern is a string of characters, in which specific substrings of characters are replaced with date and time data from a calendar when formatting, or used to generate data for a calendar when parsing. The following are examples:

Pattern Result (in a particular locale)
yyyy.MM.dd G 'at' HH:mm:ss zzz 1996.07.10 AD at 15:08:56 PDT
EEE, MMM d, ''yy Wed, July 10, '96
h:mm a 12:08 PM
hh 'o''clock' a, zzzz 12 o'clock PM, Pacific Daylight Time
K:mm a, z 0:00 PM, PST
yyyyy.MMMM.dd GGG hh:mm aaa 01996.July.10 AD 12:08 PM

When parsing using a pattern, a lenient parse should be used; see Parsing Dates and Times.

The Date Field Symbol Table below contains the characters used in patterns to show the appropriate formats for a given locale, such as yyyy for the year. Characters may be used multiple times. For example, if y is used for the year, 'yy' might produce '99', whereas 'yyyy' produces '1999'. For most numerical fields, the number of characters specifies the field width. For example, if h is the hour, 'h' might produce '5', but 'hh' produces '05'. For some characters, the count specifies whether an abbreviated or full form should be used, but may have other choices, as given below.

<!ATTLIST pattern numbers CDATA #IMPLIED >

The numbers attribute is used to indicate that numeric quantities in the pattern are to be rendered using a numbering system other than then default numbering system defined for the given locale. The attribute can be in one of two forms. If the alternate numbering system is intended to apply to ALL numeric quantities in the pattern, then simply use the numbering system ID as found in Numbering Systems. To apply the alternate numbering system only to a single field, the syntax "<letter>=<numberingSystem>" can be used one or more times, separated by semicolons.

Examples:
<pattern numbers="hebr">dd/mm/yyyy</pattern>
<!-- Use Hebrew numerals to represent numbers in the Hebrew calendar, where "latn" numbering system is the default -->

<pattern numbers="y=hebr">dd/mm/yyyy</pattern>
<!-- Same as above, except that ONLY the year value would be rendered in Hebrew -->

<pattern numbers="d=thai;m=hans;y=deva">dd/mm/yyyy</pattern>
<!-- Illustrates use of multiple numbering systems for a single pattern. -->

In patterns, two single quotes represents a literal single quote, either inside or outside single quotes. Text within single quotes is not interpreted in any way (except for two adjacent single quotes). Otherwise all ASCII letters from a to z and A to Z are reserved as syntax characters, and require quoting if they are to represent literal characters. In addition, certain ASCII punctuation characters may become variable in the future (for example, ":" being interpreted as the time separator and '/' as a date separator, and replaced by respective locale-sensitive characters in display).

Note: the counter-intuitive use of 5 letters for the narrow form of weekdays and months is forced by backwards compatibility.

Date Field Symbol Table
Field Sym. No. Example Description
era G 1..3 AD Era - Replaced with the Era string for the current date. One to three letters for the abbreviated form, four letters for the long (wide) form, five for the narrow form.
4 Anno Domini
5 A
year y 1..n 1996 Year. Normally the length specifies the padding, but for two letters it also specifies the maximum length. Example:
Year y yy yyy yyyy yyyyy
AD 1 1 01 001 0001 00001
AD 12 12 12 012 0012 00012
AD 123 123 23 123 0123 00123
AD 1234 1234 34 1234 1234 01234
AD 12345 12345 45 12345 12345 12345
Y 1..n 1997 Year (in "Week of Year" based calendars). Normally the length specifies the padding, but for two letters it also specifies the maximum length. This year designation is used in ISO year-week calendar as defined by ISO 8601, but can be used in non-Gregorian based calendar systems where week date processing is desired. May not always be the same value as calendar year.
u 1..n 4601 Extended year. This is a single number designating the year of this calendar system, encompassing all supra-year fields. For example, for the Julian calendar system, year numbers are positive, with an era of BCE or CE. An extended year value for the Julian calendar system assigns positive values to CE years and negative values to BCE years, with 1 BCE being year 0.
U 1..3 甲子 Cyclic year name. Calendars such as the Chinese lunar calendar (and related calendars) and the Hindu calendars use 60-year cycles of year names. Use one through three letters for the abbreviated name, four for the full (wide) name, or five for the narrow name (currently the data only provides abbreviated names, which will be used for all requested name widths). If the calendar does not provide cyclic year name data, or if the year value to be formatted is out of the range of years for which cyclic name data is provided, then numeric formatting is used (behaves like 'y').
4 (currently also 甲子)
5 (currently also 甲子)
r 1..n 1996 Related Gregorian year. For non-Gregorian calendars, this corresponds to the extended Gregorian year in which the calendar’s year begins. Related Gregorian years are often displayed, for example, when formatting dates in the Japanese calendar — e.g. “2012(平成24)年1月15日” — or in the Chinese calendar — e.g. “2012壬辰年腊月初四”. The related Gregorian year is usually displayed using the "latn" numbering system, regardless of what numbering systems may be used for other parts of the formatted date. If the calendar’s year is linked to the solar year (perhaps using leap months), then for that calendar the 'r' year will always be at a fixed offset from the 'u' year. For the Gregorian calendar, the 'r' year is the same as the 'u' year.
quarter Q 1..2 02 Quarter - Use one or two for the numerical quarter, three for the abbreviation, four for the full (wide) name, or five for the narrow name.
3 Q2
4 2nd quarter
5 2
q 1..2 02 Stand-Alone Quarter - Use one or two for the numerical quarter, three for the abbreviation, four for the full name, or five for the narrow name.
3 Q2
4 2nd quarter
5 2
month M 1..2 09 Month - Use one or two for the numerical month, three for the abbreviation, four for the full (wide) name, or five for the narrow name. With two ("MM"), the month number is zero-padded if necessary (e.g. "08").
3 Sept
4 September
5 S
L 1..2 09 Stand-Alone Month - Use one or two for the numerical month, three for the abbreviation, four for the full (wide) name, or 5 for the narrow name. With two ("LL"), the month number is zero-padded if necessary (e.g. "08").
3 Sept
4 September
5 S
l 1 (nothing) This pattern character is deprecated, and should be ignored in patterns. It was originally intended to be used in combination with M to indicate placement of the symbol for leap month in the Chinese calendar. Placement of that marker is now specified using locale-specific <monthPatterns> data, and formatting and parsing of that marker should be handled as part of supporting the regular M and L pattern characters.
week w 1..2 27 Week of Year. Use "w" to show the minimum number of digits, or "ww" to always show two digits (zero-padding if necessary, e.g. "08").
W 1 3 Week of Month
day d 1..2 1 Date - Day of the month. Use "d" to show the minimum number of digits, or "dd" to always show two digits (zero-padding if necessary, e.g. "08").
D 1..3 345 Day of year
F 1 2 Day of Week in Month. The example is for the 2nd Wed in July
g 1..n 2451334 Modified Julian day. This is different from the conventional Julian day number in two regards. First, it demarcates days at local zone midnight, rather than noon GMT. Second, it is a local number; that is, it depends on the local time zone. It can be thought of as a single number that encompasses all the date-related fields.
week
day
E 1..3 Tues Day of week - Use one through three letters for the abbreviated day name, four for the full (wide) name, five for the narrow name, or six for the short name.
4 Tuesday
5 T
6 Tu
e 1..2 2 Local day of week. Same as E except adds a numeric value that will depend on the local starting day of the week, using one or two letters. For this example, Monday is the first day of the week.
3 Tues
4 Tuesday
5 T
6 Tu
c 1 2 Stand-Alone local day of week - Use one letter for the local numeric value (same as 'e'), three for the abbreviated day name, four for the full (wide) name, five for the narrow name, or six for the short name.
3 Tues
4 Tuesday
5 T
6 Tu
period a 1-3 AM Abbreviated/short form of AM or PM
4 AM Wide form of AM or PM. May be the same as the short form if the “real” long form (eg ante meridiem) is not customarily be used.
5 a Narrow form of AM or PM. Unlike some other narrow forms, must be unique.
hour h 1..2 11 Hour [1-12]. When used in skeleton data or in a skeleton passed in an API for flexible date pattern generation, it should match the 12-hour-cycle format preferred by the locale (h or K); it should not match a 24-hour-cycle format (H or k). Use hh for zero padding.
H 1..2 13 Hour [0-23]. When used in skeleton data or in a skeleton passed in an API for flexible date pattern generation, it should match the 24-hour-cycle format preferred by the locale (H or k); it should not match a 12-hour-cycle format (h or K). Use HH for zero padding.
K 1..2 0 Hour [0-11]. When used in a skeleton, only matches K or h, see above. Use KK for zero padding.
k 1..2 24 Hour [1-24]. When used in a skeleton, only matches k or H, see above. Use kk for zero padding.
j 1..2 n/a This is a special-purpose symbol. It must not occur in pattern or skeleton data. Instead, it is reserved for use in skeletons passed to APIs doing flexible date pattern generation. In such a context, it requests the preferred hour format for the locale (h, H, K, or k), as determined by whether h, H, K, or k is used in the standard short time format for the locale. In the implementation of such an API, 'j' must be replaced by h, H, K, or k before beginning a match against availableFormats data. Note that use of 'j' in a skeleton passed to an API is the only way to have a skeleton request a locale's preferred time cycle type (12-hour or 24-hour).
J 1..2 n/a This is a special-purpose symbol. It must not occur in pattern or skeleton data. Instead, it is reserved for use in skeletons passed to APIs doing flexible date pattern generation. In such a context, like 'j', it requests the preferred hour format for the locale (h, H, K, or k). However, unlike 'j', it requests no "am/pm" marker (It is typically used where there is enough context that that is not necessary). For example, in en_US with "Jmm", 13:00 would appear as "1:00", while with "jmm", it would appear as "1:00 PM".
minute m 1..2 59 Minute. Use "m" to show the minimum number of digits, or "mm" to always show two digits (zero-padding if necessary, e.g. "08").
second s 1..2 12 Second. Use "s" to show the minimum number of digits, or "ss" to always show two digits (zero-padding if necessary, e.g. "08").
S 1..n 3456 Fractional Second - truncates (like other time fields) to the count of letters. (example shows display using pattern SSSS for seconds value 12.34567)
A 1..n 69540000 Milliseconds in day. This field behaves exactly like a composite of all time-related fields, not including the zone fields. As such, it also reflects discontinuities of those fields on DST transition days. On a day of DST onset, it will jump forward. On a day of DST cessation, it will jump backward. This reflects the fact that is must be combined with the offset field to obtain a unique local time value.
sep. : Time separator. Like the use of "," in number formats, this is a variable that can be replaced, depending on the numbering system. For more information, see Part 3: Numbers , Section 2.3 Number Symbols.
zone z 1..3 PDT The short specific non-location format. Where that is unavailable, falls back to the short localized GMT format ("O").
4 Pacific Daylight Time The long specific non-location format. Where that is unavailable, falls back to the long localized GMT format ("OOOO").
Z 1..3 -0800 The ISO8601 basic format with hours, minutes and optional seconds fields. The format is equivalent to RFC 822 zone format (when optional seconds field is absent). This is equivalent to the "xxxx" specifier.
4 GMT-8:00 The long localized GMT format. This is equivalent to the "OOOO" specifier.
5 -08:00
-07:52:58
The ISO8601 extended format with hours, minutes and optional seconds fields. The ISO8601 UTC indicator "Z" is used when local time offset is 0. This is equivalent to the "XXXXX" specifier.
O 1 GMT-8 The short localized GMT format.
4 GMT-08:00 The long localized GMT format.
v 1 PT The short generic non-location format. Where that is unavailable, falls back to the generic location format ("VVVV"), then the short localized GMT format as the final fallback.
4 Pacific Time The long generic non-location format. Where that is unavailable, falls back to generic location format ("VVVV").
V 1 uslax The short time zone ID. Where that is unavailable, the special short time zone ID unk (Unknown Zone) is used.
Note: This specifier was originally used for a variant of the short specific non-location format, but it was deprecated in the later version of this specification. In CLDR 23, the definition of the specifier was changed to designate a short time zone ID.
2 America/Los_Angeles The long time zone ID.
3 Los Angeles The exemplar city (location) for the time zone. Where that is unavailable, the localized exemplar city name for the special zone Etc/Unknown is used as the fallback (for example, "Unknown City").
4 Los Angeles Time The generic location format. Where that is unavailable, falls back to the long localized GMT format ("OOOO"; Note: Fallback is only necessary with a GMT-style Time Zone ID, like Etc/GMT-830.)
This is especially useful when presenting possible timezone choices for user selection, since the naming is more uniform than the "v" format.
X 1 -08
+0530
Z
The ISO8601 basic format with hours field and optional minutes field. The ISO8601 UTC indicator "Z" is used when local time offset is 0. (The same as x, plus "Z".)
2 -0800
Z
The ISO8601 basic format with hours and minutes fields. The ISO8601 UTC indicator "Z" is used when local time offset is 0. (The same as xx, plus "Z".)
3 -08:00
Z
The ISO8601 extended format with hours and minutes fields. The ISO8601 UTC indicator "Z" is used when local time offset is 0. (The same as xxx, plus "Z".)
4 -0800
-075258
Z
The ISO8601 basic format with hours, minutes and optional seconds fields. The ISO8601 UTC indicator "Z" is used when local time offset is 0. (The same as xxxx, plus "Z".)
Note: The seconds field is not supported by the ISO8601 specification.
5 -08:00
-07:52:58
Z
The ISO8601 extended format with hours, minutes and optional seconds fields. The ISO8601 UTC indicator "Z" is used when local time offset is 0. (The same as xxxxx, plus "Z".)
Note: The seconds field is not supported by the ISO8601 specification.
x 1 -08
+0530
The ISO8601 basic format with hours field and optional minutes field. (The same as X, minus "Z".)
2 -0800 The ISO8601 basic format with hours and minutes fields. (The same as XX, minus "Z".)
3 -08:00 The ISO8601 extended format with hours and minutes fields. (The same as XXX, minus "Z".)
4 -0800
-075258
The ISO8601 basic format with hours, minutes and optional seconds fields. (The same as XXXX, minus "Z".)
Note: The seconds field is not supported by the ISO8601 specification.
5 -08:00
-07:52:58
The ISO8601 extended format with hours, minutes and optional seconds fields. (The same as XXXXX, minus "Z".)
Note: The seconds field is not supported by the ISO8601 specification.

All non-letter characters represent themselves in a pattern, except for the single quote. It is used to 'escape' letters. Two single quotes in a row, whether inside or outside a quoted 'real' single quote.

8.1 Localized Pattern Characters (deprecated)

These are characters that can be used when displaying a date pattern to an end user. This can occur, for example, when a spreadsheet allows users to specify date patterns. Whatever is in the string is substituted one-for-one with the characters "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr", with the above meanings. Thus, for example, if 'J' is to be used instead of 'Y' to mean Year (for Week of Year), then the string would be: "GyMdkHmsSEDFwWahKzJeugAZvcLQqVUOXxr".

This element is deprecated. It is recommended instead that a more sophisticated UI be used for localization, such as using icons to represent the different formats (and lengths) in the Date Field Symbol Table.

8.2 AM / PM

Even for countries where the customary date format only has a 24 hour format, both the am and pm localized strings must be present and must be distinct from one another. Note that as long as the 24 hour format is used, these strings will normally never be used, but for testing and unusual circumstances they must be present.

8.3 Eras

There are only two values for era in the Gregorian calendar, with two common naming conventions (here in abbreviated form for English): "BC" and "AD", or "BCE" and "CE". These values can be translated into other languages, like "a.C." and and "d.C." for Spanish, but there are no other eras in the Gregorian calendar. Other calendars have a different numbers of eras. Care should be taken when translating the era names for a specific calendar.

8.4 Week of Year

Values calculated for the Week of Year field range from 1 to 53 for the Gregorian calendar (they may have different ranges for other calendars). Week 1 for a year is the first week that contains at least the specified minimum number of days from that year. Weeks between week 1 of one year and week 1 of the following year are numbered sequentially from 2 to 52 or 53 (if needed). For example, January 1, 1998 was a Thursday. If the first day of the week is MONDAY and the minimum days in a week is 4 (these are the values reflecting ISO 8601 and many national standards), then week 1 of 1998 starts on December 29, 1997, and ends on January 4, 1998. However, if the first day of the week is SUNDAY, then week 1 of 1998 starts on January 4, 1998, and ends on January 10, 1998. The first three days of 1998 are then part of week 53 of 1997.

Values are similarly calculated for the Week of Month.

8.5 Week Elements

firstDay
A number indicating which day of the week is considered the 'first' day, for calendar purposes. Because the ordering of days may vary between calendar, keywords are used for this value, such as sun, mon, …. These values will be replaced by the localized name when they are actually used.
minDays (Minimal Days in First Week)
Minimal days required in the first week of a month or year. For example, if the first week is defined as one that contains at least one day, this value will be 1. If it must contain a full seven days before it counts as the first week, then the value would be 7.
weekendStart, weekendEnd
Indicates the day and time that the weekend starts or ends. As with firstDay, keywords are used instead of numbers.

9 Parsing Dates and Times

For general information on lenient parsing, see Lenient Parsing in the core specification. This section provides additional information specific to parsing of dates and times.

Lenient parsing of date and time strings is especially complicated, due to the large number of possible fields and formats. The fields fall into two categories: numeric fields (hour, day of month, year, numeric month, and so on) and symbolic fields (era, quarter, month, weekday, AM/PM, time zone). In addition, the user may type in a date or time in a form that is significantly different from the normal format for the locale, and the application must use the locale information to figure out what the user meant. Input may well consist of nothing but a string of numbers with separators, for example, "09/05/02 09:57:33".

The input can be separated into tokens: numbers, symbols, and literal strings. Some care must be taken due to ambiguity, for example, in the Japanese locale the symbol for March is "3 月", which looks like a number followed by a literal. To avoid these problems, symbols should be checked first, and spaces should be ignored (except to delimit the tokens of the input string).

The meaning of symbol fields should be easy to determine; the problem is determining the meaning of the numeric fields. Disambiguation will likely be most successful if it is based on heuristics. Here are some rules that can help: