<div class="intro component">
    <p>
        The DataType Utility is a collection of classes that provide type-conversion and
        string-formatting convenience methods for numbers, dates, and XML documents.
    </p>

</div>

{{>getting-started}}

<h2 id="using">Using the DataType utility</h2>

<h3 id="dates">Dates</h3>

<h4 id="formattingdates">Formatting dates</h4>

<p>
    <code>Y.Date.format()</code> will output dates as strings formatted
    using <code>strftime</code> tokens. Some of the formats are localizable, so
    be sure to specify the <code>lang</code> property of the YUI instance's
    config object.
</p>

```
YUI({lang:"ko-KR"}).use("datatype-date", function(Y) {
    // display the current date and time in localized format
    Y.log(Y.Date.format(new Date(), {format:"%x %X"}));
});
```

<p>
    <a name="addDateFormat"></a>The module has support for a large number of
    languages built in.  If you need a language that's not supported, you can
    register the necessary localized data yourself using facilities of the <a
    href="../intl">Internationalization utility</a>.  The resource bundle you
    provide needs to have properties corresponding to the locale-sensitive <a
    href="{{apiDocs}}/classes/Date.html#method_format"> strftime format
    specifiers</a>:
</p>

<ul>
    <li><b>a:</b> list of abbreviated weekday names, from Sunday to Saturday
    <li><b>A:</b> list of full weekday names, from Sunday to Saturday
    <li><b>b:</b> list of abbreviated month names, from January to December
    <li><b>B:</b> list of full month names, from January to December
    <li><b>c:</b> preferred date and time representation
    <li><b>p:</b> list of strings corresponding to "AM" and "PM"
    <li><b>P:</b> same as "p", but lower case
    <li><b>x:</b> preferred date representation without the time
    <li><b>X:</b> preferred time representation without the date
</ul>

```
YUI().use("intl", "datatype-date-format", function(Y) {
    // provide data for Punjabi in India
    Y.Intl.add("datatype-date-format", "pa-IN", {
        "a":["ਐਤ.","ਸੋਮ.","ਮੰਗਲ.","ਬੁਧ.","ਵੀਰ.","ਸ਼ੁਕਰ.","ਸ਼ਨੀ."],
        "A":["ਐਤਵਾਰ","ਸੋਮਵਾਰ","ਮੰਗਲਵਾਰ","ਬੁਧਵਾਰ","ਵੀਰਵਾਰ","ਸ਼ੁੱਕਰਵਾਰ","ਸ਼ਨੀਚਰਵਾਰ"],
        "b":["ਜਨਵਰੀ","ਫ਼ਰਵਰੀ","ਮਾਰਚ","ਅਪ੍ਰੈਲ","ਮਈ","ਜੂਨ","ਜੁਲਾਈ","ਅਗਸਤ","ਸਤੰਬਰ","ਅਕਤੂਬਰ","ਨਵੰਬਰ","ਦਸੰਬਰ"],
        "B":["ਜਨਵਰੀ","ਫ਼ਰਵਰੀ","ਮਾਰਚ","ਅਪ੍ਰੈਲ","ਮਈ","ਜੂਨ","ਜੁਲਾਈ","ਅਗਸਤ","ਸਤੰਬਰ","ਅਕਤੂਬਰ","ਨਵੰਬਰ","ਦਸੰਬਰ"],
        "c":"%a, %Y %b %d %l:%M:%S %p %Z",
        "p":["ਸਵੇਰੇ","ਸ਼ਾਮ"],
        "P":["ਸਵੇਰੇ","ਸ਼ਾਮ"],
        "x":"%d/%m/%Y",
        "X":"%l:%M:%S %p"
    });
    // switch to Punjabi
    Y.Intl.setLang("datatype-date-format", "pa-IN");
    // now dates are formatted in Punjabi
    Y.log(Y.Date.format(new Date(), {format:"%A %x %X"}));
});
```

<h4 id="parsingdates">Parsing dates</h4>

<p>
    <code>Y.Date.parse()</code> accepts a value and, optionally, a formatting
    specification and converts it to a Date
    object.  If no format is given, it will pass the value to the
    JavaScript <code>Date()</code> constructor.  Invalid values will return null.
</p>

```
var date1 = Y.Date.parse("December 17, 1995 03:24:00");

var date2 = Y.Date.parse("1995,11,17");

var date3 = Y.Date.parse(948548583);

```
<p>
The `parser` function can accept the same format specification as `Y.Date.format`.
Ideally, using the same formatting specification, the two operations should
be complementary.  The `parser` method, however is more tolerant, it accepts
any number of spaces in between the parts of the date, is case-insensitive
and does not require leading zeros even when the format says so.
</p>
<p>
The `parser` function accepts an optional third argument, a `cutoff` year.
When years are given as two digits, those values below the cutoff year will
have 2000 added to them, those above, 1900.  If `cutoff` is passed as null,
the date will be taken as is. The `cutoff` defaults to 30.
</p>
```
var date1 = Y.Date.parse("00-1-1", "%F");       // Assumes Jan 1st, 2000

var date2 = Y.Date.parse("40-1-1", "%F");       // Assumes Jan 1st, 1940

var date3 = Y.Date.parse("140-1-1", "%F");      // No guessing: Jan 1st, 140

var date4 = Y.Date.parse("40-1-1", "%F", null); //  No guessing: Jan 1st, 40

```
<p>
For the purpose of the calculation, `parser` ignores the parts that do not
provide sufficient information on their own such as the names of the day of the week.
However, they are required to be present in the input string.
</p>
<p>
The `%Z` format or the composite formats that use it, such as `%c` in the `en` locale
have limited support.  It relies on a table of time zone names and abbreviations
which would be too heavy to fully load.  The module has the table filled with
a minimal set of North American and European abbreviations.
</p>
<p>
It is suggested that the developer uses different formatting specifications when
simply displaying a date and when editing it.  For displaying purposes, the format
can add more information (such as the weekday) and extra decoration.  For editing
purposes, the format should be simpler so as not to force the user to type so
much, and it should be easier and unambiguous to the parser.
</p>

<h3 id="numbers">Numbers</h3>

<h4 id="formattingnumbers">Formatting numbers</h4>

<p>
    JavaScript Number values can be formatted with a variety options into
    string values using <code>Y.Number.format()</code>.
</p>

```
Y.log(Y.Number.format(123123123.176,{
    prefix: "€",
    thousandsSeparator: ".",
    decimalSeparator: ",",
    decimalPlaces: 2,
    suffix: " (EUR)"
}));
```

<h4 id="parsingnumbers">Parsing numbers</h4>

<p>
    String values can be converted into Number objects with
    <code>Y.Number.parse()</code>.
</p>

```
var number = Y.Number.parse("123123");
```
<p>
An optional configuration can be added, compatible with that of `Y.Number.format`.
If found, any prefix, suffix, thousands separators and whitespaces will be deleted,
the decimal separator will be replaced by a dot and the resulting string parsed.
The `decimalPlaces` property is ignored and is meant for compatibility with `format`.
</p>
```
Y.log(Y.Number.parse(" € 123.123.123,176 (EUR) ",{
    prefix: "€",
    thousandsSeparator: ".",
    decimalSeparator: ",",
    decimalPlaces: 2,
    suffix: " (EUR)"
}));
```
<h3 id="xml">XML</h3>

<h4 id="formattingxml">Formatting XML</h4>

<p>
    <code>Y.XML.format()</code> will accept an XML document and return
    its string representation. Note that browsers may slightly differ in the
    exact string that is returned.
</p>

```
var myString = Y.XML.format(myXMLDocument);
```

<h4 id="parsingxml">Parsing XML</h4>

<p>
    <code>Y.XML.parse()</code> will accept a string representation of
    XML and return an XML document object. Note that browsers differ in their
    handling of invalid syntax but will in general return an XML document even
    under error conditions.
</p>

```
var myXMLDocument = Y.XML.parse("<myroot><item type='foo'><name>Abc</name><rank>1</rank></item><item type='bar'><name>Def</name><rank>2</rank></item><item type='bat'><name>Ghhi</name><rank>3</rank></item></myroot>");
```

<h3 id="parsers">Y.Parsers shortcuts</h3>

<p>
    The functions <code>Y.Date.parse()</code> and
    <code>Y.Number.parse()</code> are registered with the
    <code>Parsers</code> object for seamless integration with the DataSchema
    Utility. For dynamic type enforcing when data is being normalized against a
    schema, simply point to the appropriate function using the built-in
    shortcut in your schema definition. Parsing your data in this manner is
    essential if your numerical or date data comes over the wire as JSON, since
    all the values will be strings.
</p>

```
YUI().use("datatype", "dataschema", function(Y) {
    var data_in = {
            "results":[
                {"string":"aardvark", "number":"1", "date":"Jan 1, 2001"},
                {"string":"bat", "number":"2", "date":"Feb 2, 2002"},
                {"string":"camel", "number":"3", "date":"March 3, 2003"}
            ]
        },
        schema = {
            resultListLocator: "results",
            resultFields: [
                "string", // needs no parsing
                {key:"number", parser: "number"}, // converts string values to numbers
                {key:"date", parser: "date"}] // converts string values to dates
        },
        data_out = Y.DataSchema.JSON.apply(schema, data_in);
});
```
