BDE 4.14.0 Production release
|
Provide a value-semantic type representing both date and time.
This component implements a value-semantic type, bdlt::Datetime
, that represents the composition of a date and a time value. The combined "date+time" value of a bdlt::Datetime
object is expressed textually as "yyyy/mm/dd_hh:mm:ss.ssssss", where "yyyy/mm/dd" represents the "date" part of the value and "hh:mm:ss.ssssss" represents the "time" part.
In addition to the usual value-semantic complement of methods for getting and setting value, the bdlt::Datetime
class provides methods and operators for making relative adjustments to value (addDays
, addTime
, addHours
, etc.). In particular, note that adding units of time to a bdlt::Datetime
object can affect the values of both the time and date parts of the object. For example, invoking addHours(2)
on a bdlt::Datetime
object whose value is "1987/10/03_22:30:00.000000" updates the value to "1987/10/04_00:30:00.000000".
The "date" part of a bdlt::Datetime
value has a range of validity identical to a bdlt::Date
object – i.e., valid dates (according to the Unix [POSIX] calendar) having years in the range [1 .. 9999]
. The valid time values are [00:00:00.000000 .. 23:59:59.999999]
. Furthermore, the unset time value (i.e., 24:00:00.000000, corresponding to the default constructed value for bdlt::Time
) is available for every valid date. Note that the supported range of time does not allow for the injection of leap seconds. The value "0001/01/01_24:00:00.000000" is the default constructed value of bdlt::Datetime
.
Furthermore, consistent with the bdlt::Time
type, a bdlt::Datetime
object whose "time" part has the default constructed value, behaves the same, with respect to manipulators and (most) free operators, as if the "time" part had the value 00:00:00.000000. As for bdlt::Time
, the behavior of all bdlt::Datetime
relational comparison operators is undefined if the "time" part of either operand is 24:00:00.000000. Consequently, bdlt::Datetime
objects whose "time" part has the default constructed value must not be used as keys for the standard associative containers, since operator<
is not defined for such objects.
Conceptually, the two primary attributes of bdlt::Datetime
are the constituent date and time values. These attributes are given the special designation "part" in this component (i.e., the "time" part and the "date" part, respectively) to distinguish them from the many other attributes (see below) that derive from these two main parts.
A bdlt::Datetime
object can be used in terms of its "date" and "time" parts or, if appropriate to an application, the object can be viewed as a single, integrated type having the combined individual attributes of date and time. Accessors and manipulators are provided for each of these eight (derived) attributes:
There are two additional "date" part attributes to bdlt::Datetime
:
where dayOfYear
tracks the value of year/month/day
(and vice versa), and dayOfWeek
can be accessed but not explicitly set.
A common standard text representation of a date and time value is described by ISO 8601. BDE provides the bdlt_iso8601util component for conversion to and from the standard ISO8601 format.
This section illustrates intended use of this component.
Values represented by objects of type bdlt::Datetime
are used widely in practice. The values of the individual attributes resulting from a default-constructed bdlt::Datetime
object, dt
, are "0001/01/01_24:00:00.000000":
We can then set dt
to have a specific value, say, 8:43pm on January 6, 2013:
Now suppose we add 6 hours and 9 seconds to this value. There is more than one way to do it:
Notice that (in both cases) the date changed as a result of adding time; however, changing just the date never affects the time:
We can also add more than a day's worth of time:
The individual arguments can also be negative:
Finally, we stream the value of dt2
to stdout
:
The streaming operator produces the following output on stdout
:
Calculations involving date and time values are difficult to get correct manually; consequently, people tend to schedule events on natural time boundaries (e.g., on the hour) even if that is sub-optimal. Having a class such as bdlt::Datetime
makes doing date and time calculations trivial.
Suppose one wants to divide into an arbitrary interval such as the time between sunset and sunrise into an arbitrary number (say 7) of equal intervals (perhaps to use as a duty roster for teams making astronomical observations).
First, we create objects containing values for the start and end of the time interval:
Then, we calculate the length of each shift in milliseconds (for good precision – we may be synchronizing astronomical instruments). Note that the difference of sunrise
and sunset
creates a temporary bdlt::DatetimeInterval
object:
Now, we calculate (and print to stdout
) the beginning and end times for each shift:
Finally, we observe:
Notice how our objects (since they manage both "date" and "time of day" parts of each point in time) seamlessly handle the transition between the two days.