# Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. — Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

# Numbers, Time and Currency formatting and parsing

All formatting and parsing is performed via the standard I/O streams. Each of the above information types is represented as a number. The formatting information is set using iostream manipulators. All manipulators are placed in the boost::locale::as namespace.

For example:

        cout << as::currency << 123.45 << endl;
        // display 123.45 in local currency representation.
        cin >> as::currency >> x ;
        // Parse currency representation and store it in x

There is a special manipulator `as::posix` that "unsets" locale-specific settings and returns them to the default `iostream` formatting and parsing methods. Please note, such formats may still be localized by the default `std::num_put` and `std::num_get` facets.

## Numbers and number manipulators

Here are the manipulators for number formatting:

- `as::number` -- format number according to local specifications, it takes into account various `std::ios_base` flags like scientific format and precision.
- `as::percent` -- format number as "percent" format. For example:

              cout << as::percent << 0.25 <<endl;

  Would create an output that may look like this:

          25%

- `as::spellout` -- spell the number. For example, under the English locale, 103 may be displayed as "one hundred three". Note: not all locales provide rules for spelling numbers. In such a case the number would be displayed in decimal format.
- `as::ordinal` -- display an order-of element. For example "2" would be displayed as "2nd" under the English locale. As in the above case, not all locales provide ordinal rules.

## Currency formatting

These are the manipulators for currency formatting:

- `as::currency` -- set the format to currency mode.
- `as::currency_iso` -- change the currency format to international, like "USD" instead of "$". This flag is supported when using ICU 4.2 and above.
- `as::currency_national` -- change currency format to national, like "$".
- `as::currency_default` -- return to the default (national) currency format.

Note:
  `as::currency_XYZ` manipulators have no effect on general formatting, only on the currency format. You must use both currency and number manipulators to use a non-default format.

## Date and Time formatting

Dates and times are represented as POSIX time. When date-time formatting is turned on in the `iostream`, each number is treated as a POSIX time. The number may be an integer or a double.

There are four major manipulators for Date and Time formatting:

- `as::date` -- date only
- `as::time` -- time only
- `as::datetime` -- both date and time
- `as::ftime` -- parameterized manipulator that allows specification of time in the format that is used in the `strftime` function. Note: not all formatting flags of `strftime` are supported.

For example:

        time_t now=time(0);
        cout << "Today is "<< as::date << now << " and tomorrow is " << now+24*3600 << endl;
        cout << "Current time is "<< as::time << now << endl;
        cout << "The current weekday is "<< as::ftime("%A") << now << endl;

More fine-grained control of date-time formatting is also available:

- `as::time_default` , `as::time_short` , `as::time_medium` , `as::time_long` , `as::time_full` -- change time formatting.
- `as::date_default` , `as::date_short` , `as::date_medium` , `as::date_long` , `as::date_full` -- change date formatting.

These manipulators, when used together with the `as::date`, `as::time`, or `as::datetime` manipulators, change the date-time representation. The default format is medium.

By default, the date and time are shown in the local time zone. This behavior may be changed with the following manipulators:

- `as::gmt` -- display date and time in GMT.
- `as::local_time` -- display in local time zone (default).
- `as::time_zone` -- parameterized manipulator that sets the time-zone ID for date-time formatting and parsing. It takes a string parameter that represents the time zone ID.

For example:

        double now=time(0);
        cout << as::datetime << as::local_time << "Local time is: "<< now << endl;
        cout << as::gmt << "GMT Time is: "<< now <<endl;
        cout << as::time_zone("EST") << "Eastern Standard Time is: "<< now <<endl;

There is a list of supported `strftime` flags by ICU backend:

- `%a` -- Abbreviated weekday (Sun.)
- `%A` -- Full weekday (Sunday)
- `%b` -- Abbreviated month (Jan.)
- `%B` -- Full month (January)
- `%c` -- Locale date-time format. Note: prefer using `as::datetime`
- `%d` -- Day of Month [01,31]
- `%e` -- Day of Month [1,31]
- `%h` -- Same as `%b`
- `%H` -- 24 clock hour [00,23]
- `%I` -- 12 clock hour [01,12]
- `%j` -- Day of year [1,366]
- `%m` -- Month [01,12]
- `%M` -- Minute [00,59]
- `%n` -- New Line
- `%p` -- AM/PM in locale representation
- `%r` -- Time with AM/PM, same as `%I:%M:%S` %p
- `%R` -- Same as `%H:%M`
- `%S` -- Second [00,61]
- `%t` -- Tab character
- `%T` -- Same as `%H:%M:%S`
- `%x` -- Local date representation. **Note:** prefer using `as::date`
- `%X` -- Local time representation. **Note:** prefer using `as::time`
- `%y` -- Year [00,99]
- `%Y` -- 4 digits year. (2009)
- `%Z` -- Time Zone
- `%%` -- Percent symbol

Unsupported `strftime` flags are: `%C` , `%u` , `%U` , `%V` , `%w` , `%W` . Also, the `O` and `E` modifiers are not supported.

General recommendations

- Prefer using generic date-time manipulators rather than specifying the full format using `as::ftime`.
- Remember that current calendars may be not Gregorian.

## Internals

Formatting information is stored in a stream class by using the `xalloc`, `pword`, and `register_callback` member functions of `std::ios_base` . All the information is stored and managed using a special object bound to `iostream`, and the manipulators just change its state.

When a number is written to or read from the stream, a custom Boost.Locale facet accesses the object and checks the required formatting information. Then it creates a special object that actually formats the number and caches it in the `iostream`. The next time a number is written to the stream, the same formatter would be used unless some flags had changed and formatter object is invalid.