Chapter 27. Date and time intervals


Loading timezone files
Local time
Generic interval parser

An x::hms object parses a time interval down to individual hour, minute, and second values:

#include <x/hms.H>

x::hms interval("1 hour, 10 minutes, 30 seconds");

Several different constructors are available to instantiate x::hms objects. This class contains three members: h, m, and s, which represent the deconstructed time interval.

An x::ymd object stores a date value:

#include <x/ymd.H>

x::locale en_us(x::locale::create("en_US.utf-8"));

x::ymd independence_day(1776, 7, 4);

independence_day += x::ymd::interval("200 years");

std::cout << independence_day.format_date("%F", en_us) << std::endl;

x::ymd implements increment and decrement operators, which adjust the date by one day. It also implements an addition operator with either a integer, interpreted as a number of days, or with the x::ymd::interval class, which specifies an arbitrary interval in terms of days, weeks, months, and or years. Adding or subtracting an x::ymd::interval to a x::ymd adjusts x::ymd's date accordingly. Subtracting two x::ymd objects results in an integer giving the number of days between the dates. get_year(), get_month(), and get_day() methods return the corresponding portions of the date value.

x::hms objects may also be added or subtracted together. Addition results in another x::hms object, whose m and s members are normalized to the range of 00-59 (or the range -59 to 00, for negative time intervals). Adding or subtracting an integer is interpreted as adding or subtracting the given number of seconds; the resulting x::hms object is also normalized. An x::ymd::interval object that specifies a number of days or weeks may also be added/subtracted to x::hms, which is equivalent to adding or subtracting the equivalent number of seconds.

x::ymd and x::hms have overloaded convenience methods that instantiate a x::strftime object, and use it to format the date or the time value as a string.

x::ymd's format_date() method formats the date as a string. Its second parameter is an optional locale:

#include <x/ymd.H>

x::ymd::iso8601 firstDayOfYear(2009, 1, 1);

x::locale en_us(x::locale::create("en_US.utf-8"));

std::cout << x::ymd(firstDayOfYear).format_date("%F", en_us) << std::endl;

x::ymd::8601 represents an ISO 8601 date, defining a date as a year, week, and day number. The ISO 8601 date object is convertible to and from a regular x::ymd object.

The x::ymd object can be casted directly into a string, which results in the %X conversion in the global locale:

#include <x/ymd.H>

x::ymd::iso8601 firstDayOfYear(2009, 1, 1);


std::cout << (std::string)x::ymd(firstDayOfYear) << std::endl;

See the reference documentation for x::hms and x::ymd for more information on formatting these classes.

An x::ymd::parser object initializes x::ymd objects from a text string.

#include <x/ymd.H>

x::locale en_us(x::locale::create("en_US.utf-8"));

x::ymd::parser<char> dateParser(en_us);

x::ymd independence_day(dateParser.parse("July 4, 1776"));

parser() understands a wide variety of date formats, including dddd-dd-dd, a string with a two digit day number, a month name, and a four digit year, in any order, as well as dddd-Wdd-dd, the ISO8601 date format.


dd/dd/dddd uses the system environment locale to interpret this as either day/month/year or month/day/year. Use mdy() to explicitly set whether this gets parsed as mm/dd/yyyy (the US date format), or dd/mm/yyyy.

Loading timezone files

#include <x/tzfile.H>

x::tzfile nyc(x::tzfile::create("America/New_York")),

x::tzfile is a reference to a reference-counted object that specifies a timezone. The only thing that can be done to a timezone object is to create it, by loading a timezone specification from the system timezone database. Timezone objects offer no useful methods of their own, they are used in conjunction with x::ymdhms and x::strftime objects.

This is an independent timezone implementation that is not related to timezone support in the standard C library, but it uses the same timezone library. This implementation does not include some obscure features of the standard C library's timezone implementation, which are unlikely to be in actual use. Namely, if the C library does not find a timezone entry with the specified name, the C library attempts to parse the specified name as a literal POSIX timezone string, and manufacture a timezone record from the literal timezone string.

In this implementation, the timezone name must always refer to an existing entry in the system timezone database. Specifying a nonexistent timezone throws an exception. x::tzfile::base::utc() returns a reference to a timezone object referring to the linear UTC timezone. x::tzfile::base::local() returns a reference to a timezone object referring to the system's default timezone, or to the UTC timezone if the system's default timezone cannot be determined. Both x::tzfile::base::utc() and x::tzfile::base::local() create their corresponding objects the first time they're called. Subsequent invocations return a reference to the same object, which gets destroyed when the application terminates. For this reason, these two functions cannot be used in object destructors which can also be invoked when the application terminates, since the order in which objects get destroyed at application shutdown is not specified.