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
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.
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;
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.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.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.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 onlyas::time -- time onlyas::datetime -- both date and timeas::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 symbolUnsupported strftime flags are: %C , %u , %U , %V , %w , %W . Also, the O and E modifiers are not supported.
General recommendations
as::ftime.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.