BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt.h
Go to the documentation of this file.
1/// @file bdlt.h
2///
3///
4/// @defgroup bdlt Package bdlt
5/// @brief Basic Development Library Time (bdlt)
6/// @addtogroup bdl
7/// @{
8/// @addtogroup bdlt
9/// [bdlt]: group__bdlt.html
10/// @{
11///
12/// # Purpose {#bdlt-purpose}
13/// Provide date and time vocabulary types, and related utilities.
14///
15/// # Mnemonic {#bdlt-mnemonic}
16/// Basic Development Library Time (bdlt)
17///
18/// # Description {#bdlt-description}
19/// The 'bdlt' ("Basic Development Library Time") package provides
20/// vocabulary types for representing date, time, and datetime values, and
21/// utilities providing non-primitive functionality on the value types.
22///
23/// Additional utilities provide:
24/// * Current date, time, and local-time offset values.
25/// * Conversion between different date and time representations.
26/// * Arithmetic and validation functions
27///
28/// See {Value Types} and {Utilities} below for overviews of the types and
29/// functions provided by this package.
30///
31/// ## Hierarchical Synopsis
32///
33/// The 'bdlt' package currently has 41 components having 9 levels of physical
34/// dependency. The list below shows the hierarchical ordering of the components.
35/// The order of components within each level is not architecturally significant,
36/// just alphabetical.
37/// @code
38/// 9. bdlt_defaultcalendarcache
39/// bdlt_defaulttimetablecache
40///
41/// 8. bdlt_calendarcache
42/// bdlt_timetablecache
43///
44/// 7. bdlt_currenttime
45/// bdlt_fixutil
46/// bdlt_iso8601util
47///
48/// 6. bdlt_calendarutil
49/// bdlt_datetimetz
50/// bdlt_localtimeoffset
51/// bdlt_timetableloader
52///
53/// 5. bdlt_calendar
54/// bdlt_calendarloader
55/// bdlt_datetimeutil
56/// bdlt_datetz
57/// bdlt_epochutil
58/// bdlt_timetable
59///
60/// 4. bdlt_datetime
61/// bdlt_dateutil
62/// bdlt_fuzzutil
63/// bdlt_packedcalendar
64/// bdlt_timetz
65/// bdlt_timeutil
66///
67/// 3. bdlt_date
68/// bdlt_datetimeintervalutil
69/// bdlt_intervalconversionutil
70/// bdlt_time
71///
72/// 2. bdlt_datetimeimputil
73/// bdlt_datetimeinterval
74/// bdlt_dayofweekset
75/// bdlt_dayofweekutil
76/// bdlt_serialdateimputil
77///
78/// 1. bdlt_calendarreverseiteratoradapter
79/// bdlt_dayofweek
80/// bdlt_fixutilconfiguration
81/// bdlt_iso8601utilconfiguration
82/// bdlt_iso8601utilparseconfiguration
83/// bdlt_monthofyear
84/// bdlt_posixdateimputil
85/// bdlt_prolepticdateimputil
86/// bdlt_timeunitratio
87/// @endcode
88///
89/// ## Component Synopsis
90///
91/// @ref bdlt_calendar :
92/// Provide fast repository for accessing weekend/holiday information.
93///
94/// @ref bdlt_calendarcache :
95/// Provide an efficient cache for read-only `bdlt::Calendar` objects.
96///
97/// @ref bdlt_calendarloader :
98/// Provide a protocol (or pure interface) for loading calendars.
99///
100/// @ref bdlt_calendarreverseiteratoradapter :
101/// Provide reverse iterator adapter for calendar iterators.
102///
103/// @ref bdlt_calendarutil :
104/// Provide common date manipulations requiring a calendar.
105///
106/// @ref bdlt_currenttime :
107/// Provide utilities to retrieve the current time.
108///
109/// @ref bdlt_date :
110/// Provide a value-semantic type to represent dates.
111///
112/// @ref bdlt_datetime :
113/// Provide a value-semantic type representing both date and time.
114///
115/// @ref bdlt_datetimeimputil :
116/// Provide constants useful for encoding datetimes.
117///
118/// @ref bdlt_datetimeinterval :
119/// Provide a representation of an interval of time.
120///
121/// @ref bdlt_datetimeintervalutil :
122/// Provide non-primitive operations on `bdlt::DatetimeInterval`.
123///
124/// @ref bdlt_datetimetz :
125/// Provide a representation of a date and time with time zone offset.
126///
127/// @ref bdlt_datetimeutil :
128/// Provide common non-primitive operations on `bdlt::Datetime`.
129///
130/// @ref bdlt_datetz :
131/// Provide a representation of a date with time zone offset.
132///
133/// @ref bdlt_dateutil :
134/// Provide common non-primitive operations on date objects.
135///
136/// @ref bdlt_dayofweek :
137/// Provide an enumeration of the set of days of the week.
138///
139/// @ref bdlt_dayofweekset :
140/// Provide an ordered set of (unique) `bdlt::DayOfWeek::Enum` values.
141///
142/// @ref bdlt_dayofweekutil :
143/// Provide common non-primitive operations on `bdlt::DayOfWeek::Enum`.
144///
145/// @ref bdlt_defaultcalendarcache :
146/// Provide a process-wide default `bdlt::CalendarCache` object.
147///
148/// @ref bdlt_defaulttimetablecache :
149/// Provide a process-wide default `bdlt::TimetableCache` object.
150///
151/// @ref bdlt_epochutil :
152/// Conversion between absolute/relative time with respect to epoch.
153///
154/// @ref bdlt_fixutil :
155/// Provide conversions between date/time objects and FIX strings.
156///
157/// @ref bdlt_fixutilconfiguration :
158/// Provide an attribute class to configure FIX string generation.
159///
160/// @ref bdlt_fuzzutil :
161/// Provide creation of `bdlt` data types from fuzz data.
162///
163/// @ref bdlt_intervalconversionutil :
164/// Provide functions to convert between time-interval representations.
165///
166/// @ref bdlt_iso8601util :
167/// Provide conversions between date/time objects and ISO 8601 strings.
168///
169/// @ref bdlt_iso8601utilconfiguration :
170/// Provide an attribute class to configure ISO 8601 string generation.
171///
172/// @ref bdlt_iso8601utilparseconfiguration :
173/// Provide an attribute class to configure ISO 8601 string parsing.
174///
175/// @ref bdlt_localtimeoffset :
176/// Provide utilities to retrieve the local time offset.
177///
178/// @ref bdlt_monthofyear :
179/// Enumerate the set of month-of-year values.
180///
181/// @ref bdlt_packedcalendar :
182/// Provide a compact repository for weekend/holiday information.
183///
184/// @ref bdlt_posixdateimputil :
185/// Provide low-level support functions for date-value manipulation.
186///
187/// @ref bdlt_prolepticdateimputil :
188/// Provide low-level support functions for date-value manipulation.
189///
190/// @ref bdlt_serialdateimputil :
191/// Provide low-level support functions for date-value manipulation.
192///
193/// @ref bdlt_time :
194/// Provide a value-semantic type representing time-of-day.
195///
196/// @ref bdlt_timetable :
197/// Provide a repository for accessing timetable information.
198///
199/// @ref bdlt_timetablecache :
200/// Provide an efficient cache for read-only `bdlt::Timetable` objects.
201///
202/// @ref bdlt_timetableloader :
203/// Provide a protocol (or pure interface) for loading timetables.
204///
205/// @ref bdlt_timetz :
206/// Provide a representation of a time with time zone offset.
207///
208/// @ref bdlt_timeunitratio :
209/// Provide constants characterizing ratios between common time units.
210///
211/// @ref bdlt_timeutil :
212/// Provide common non-primitive operations on `bdlt::Time`.
213///
214/// ## Value Types
215///
216/// This package defines value-semantic types that represent dates, times (of
217/// day), and combined date and time values. For each of these "time" types,
218/// there is a related type that also holds a time offset value from UTC. There
219/// are also enumerated types representing the months of the year and the days of
220/// the week.
221///
222/// ### Value Types: Date, Time and Datetime
223///
224/// The 'bdlt' package defines 'bdlt::Date' to represent date values, 'bdlt::Time'
225/// to represent time values (to microsecond resolution) within a day, and the
226/// combined 'bdlt::Datetime' to represent all points in time (to microsecond
227/// resolution) across the range of date values. The ranges of each type are
228/// shown below.
229/// @code
230/// Type Range
231/// ------- ------------------------------------------------------------
232/// Date [0001/01/01 .. 9999/12/31 ]
233/// Time [ 00:00:00.000000 .. 23:59:59.999999 ]
234/// Datetime [0001/01/01_00:00:00.000000 .. 9999/12/31_23:59:59.999999 ]
235/// @endcode
236/// Further note that:
237/// * The date values follow the Unix (POSIX) calendar (see {@ref bdlt_date }.
238/// * The definition of 'bdlt::Datetime' does *not* allow for leap seconds.
239///
240/// The above classes define values representing points on a timeline (e.g., dates
241/// on a calendar, positions on a clock) whereas the 'bdlt::DatetimeInterval'
242/// class represents the *difference* (to microsecond resolution) between those
243/// points.
244/// @code
245/// Type Difference Type
246/// ------- ----------------
247/// Date int (days)
248/// Time DatetimeInterval
249/// Datetime DatetimeInterval
250/// DatetimeInterval DatetimeInterval
251/// @endcode
252/// Each of these classes are designed to hold date and time values, but do not
253/// themselves provide means for obtaining values such as current time and date.
254/// Those values are available via separate utility components. See {Obtaining
255/// Current Date, Time, and Local-Time Offset Values}.
256///
257////Singular 'Time' and 'Datetime' Values
258////- - - - - - - - - - - - -
259/// The 'bdlt::Time' class defines a singular value, "24:00:00.000000", which is
260/// also the default-constructed value. This singular value is distinguished in
261/// two ways:
262///
263/// * Relational comparisons to other time values are disallowed -- the behavior
264/// is undefined. Note that comparisons of equality and inequality to other
265/// values *are* legal.
266///
267/// * Note that the singular value cannot appear as a key value in any of the
268/// standard ordered containers (which require weak ordering of keys).
269///
270/// * The singular value is implicitly converted to "00:00:00.000000" (midnight)
271/// in arithmetic operations using 'bdlt::Time' values.
272///
273/// Similarly, the 'bdlt::Datetime' class defines one singular value,
274/// "0001/01/01_24:00:00.000000", which happens to be the default constructed
275/// value. The restrictions and semantics of this value parallel those of the
276/// singular 'bdlt::Time' value.
277///
278/// Some applications use the singular values of these types as placeholders when
279/// a value must be provided but is not known. (See @ref bdetu_unset .)
280///
281/// ### Timezone Augmented Value Types: DateTz, TimeTz and DatetimeTz
282///
283/// For each of the basic date and time types there is a corresponding
284/// value-semantic type that is augmented with a value representing an offset (in
285/// minutes) from UTC. Note that other BDE types represent local time offset as
286/// seconds (e.g., the 'seconds' attribute of 'bsls::TimeInterval').
287///
288/// The local time offset augmented types are:
289/// @code
290/// Basis Type Augmented Type
291/// ---------- ----------------
292/// bldt:Date bdlt::DateTz
293/// bldt:Time bdlt::TimeTz
294/// bldt:Datetime bdlt::DatetimeTz
295/// @endcode
296/// These types are not normalized to a common time zone when they are compared,
297/// hence, equality between objects of any of these types requires that the object
298/// have both the same local time and the same local-time offset values. To
299/// determine *equivalence* between such objects, each of these classes provides a
300/// 'utc*' accessor method.
301///
302/// These types themselves do not validate that the combinations of dates, times,
303/// and local-time offset values they hold correspond to a valid time in any
304/// officially recognized time zone. See {Obtaining Current Date, Time, and
305/// Local-Time Offset Values}.
306///
307/// ### Enumerated Values
308///
309/// The 'bdlt' package provides enumerations in @ref bdlt_monthofyear and
310/// @ref bdlt_dayofweek . The @ref bdlt_dayofweekset provides an efficient, ordered
311/// container of unique 'btdl::DayofWeek::Enum' values (i.e., containing no more
312/// than seven elements).
313///
314/// ## Utilities
315///
316/// This package provides utility components that:
317///
318/// * Provide current date, time, and local-time offset values.
319/// * Provide date arithmetic functions.
320/// * Provide a wide variety of conversion methods: between the value types
321/// defined in this package, between the package value types and standard types
322/// for date and time, between time values in different standard units (e.g.,
323/// hours, minutes, nanoseconds).
324///
325/// ### Obtaining Current Date, Time, and Local-Time Offset Values
326///
327/// The @ref bdlt_currenttime component provides:
328///
329/// * A 'bdlt::Datetime' value for the current UTC time.
330/// * A 'bdlt::Datetime' value for the current local time.
331/// * A 'bsls::TimeInterval' from the start of the epoch.
332///
333/// The @ref bdlt_localtimeoffset component defines a function that returns the
334/// offset of the host machines designated time zone (as set by the system
335/// administrator) from UTC, including adjustments between standard and
336/// daylight-saving time, as of a given UTC time and date. For local-time offset
337/// for arbitrary time zones see the {'baetzo'} package.
338///
339/// Both 'bdlt::CurrentTime' and 'bdlt::LocalTimeOffset' obtain their values via
340/// user-installed callback functions. The default callbacks obtain their values
341/// from platform appropriate system calls. User-defined callbacks can provide
342/// high-performance (e.g., cached) alternatives to the default system calls, can
343/// be instrumented to gather statistics, and can simulate the passage of time for
344/// test scenarios.
345///
346/// ### Advanced Date Arithmetic: bdlt::DateUtil
347///
348/// The @ref bdet_dateutil component provides functions on 'bdlt::Date' values that
349/// extend those provided by the 'bdlt::Date' class itself. For example:
350///
351/// * Calculate the 'bdlt::Date' that is a specified number of months -- or years
352/// -- before or after a given date. Two different end-of-month conventions
353/// are provided.
354///
355/// * Find the next -- or previous -- occurrence of a given day of week relative
356/// to a specified date (inclusive or exclusive of that specified date).
357///
358/// * Find the date of a specified day of week that is the *nth* (e.g., 1st, 3rd)
359/// or last occurrence in a specified year and month.
360///
361/// This utility also provides a function for conversion of 'bdlt::Date' values to
362/// and from 'int' values in the "YYYYMMDD" format.
363///
364/// ### Conversion of Date, Time and Datetime Values
365///
366/// Several utility components of 'bdlt' provide functions for the conversion of
367/// date and time types to other types, some defined in the C++ Standard, others
368/// defined elsewhere in BDE. In particular, the @ref bdlt_epochutil component
369/// provides functions that convert 'bdlt::Datetime' values (in UTC) -- understood
370/// to represent an absolute date and time in UTC -- to equivalent difference
371/// values measured from the start of the Unix standard epoch
372/// (1970/01/01_00:00:00.000000 UTC).
373/// @code
374/// Component Conversions
375/// ----------------- --------------------------------------------------------
376/// bdlt_dateutil bdlt::Date <=> 'int' in "YYYYMMDD" format
377///
378/// bdlt_datetimeutil bdlt::Datetime <=> bsl::tm
379///
380/// bdlt_epochutil bdlt::Datetime <=> bsl::time_t from the epoch
381/// bdlt::Datetime <=> bdlt::TimeT64 from the epoch
382/// bdlt::Datetime <=> bsls::TimeInterval from the epoch
383/// bdlt::Datetime <=> bdlt::DateTimeInterval from the epoch
384///
385/// bdlt_intervalconversionutil
386/// bdlt::DatetimeInterval
387/// <=> bsls::TimeInterval
388/// bdlt_serialdateimputil
389/// bdlt::Date <=> 'int' in the range '[1 .. 3652059]'
390/// (corresponding to
391/// '[00001/01/01 .. 9999/12/31]')
392/// @endcode
393///
394/// ### Conversion of Conventional Time Units
395///
396/// The @ref bdlt_timeunitratio component provides a set of constants that express
397/// the ratios between standard time units such as days, hours, ..., nanoseconds.
398/// One example is 'bdlt::TimeUnitRatio::k_MILLISECONDS_PER_MINUTE'.
399///
400/// ## Usage
401///
402/// This section illustrates intended use of these components.
403///
404/// ### Example 1: Celebrating Milestone Dates
405///
406/// Date and time calculations are simple in principle but tedious and error-
407/// prone in practice. Consequently, people tend to schedule events on dates that
408/// are easy to calculate -- e.g., first of the month, anniversary dates -- even
409/// though we know that not all months and years express intervals of the same
410/// length. Access to a rich set of types and utilities for date and time
411/// calculations affords us other options.
412///
413/// Suppose we wish to commemorate the 20,000th day since our birth.
414///
415/// First, create a 'bdlt::Datetime' object to represent our date of birth. Let
416/// us assume that we were born at the exact start of the Unix epoch:
417/// @code
418/// bdlt::Datetime dtBirthday = bdlt::EpochUtil::epoch();
419/// assert(bdlt::Datetime(1970, 1, 1, 0, 0, 0, 0) == dtBirthday);
420/// @endcode
421/// Next, we calculate the milestone date (and time).
422/// @code
423/// bdlt::Datetime dt20k(dtBirthday); dt20k.addDays(20000);
424/// assert(bdlt::DatetimeInterval(20000) == dt20k - dtBirthday);
425///
426/// bsl::cout << dt20k << bsl::endl;
427/// @endcode
428/// and find:
429/// @code
430/// 04OCT2024_00:00:00.000000
431/// @endcode
432/// The above value represents UTC date and time values. We, however, plan to
433/// celebrate the milestone in New York City. Thus, we must obtain the local time
434/// offset in NYC for that future date and use it to calculate the milestone
435/// (date) in that time zone.
436/// @code
437/// bsls::TimeInterval localTimeOffset =
438/// bdlt::LocalTimeOffset::localTimeOffset(dt20k);
439///
440/// bdlt::DatetimeInterval dtOffset =
441/// bdlt::IntervalConversionUtil::convertToDatetimeInterval(localTimeOffset);
442///
443/// bdlt::DatetimeTz dtz20kLocal(
444/// dt20k + dtOffset,
445/// static_cast<int>(dtOffset.totalMinutes()));
446///
447/// bsl::cout << dtz20kLocal << bsl::endl;
448/// @endcode
449/// which is one calendar day earlier:
450/// @code
451/// 03OCT2024_20:00:00.000000-0400
452/// @endcode
453/// Notice that the local time offset was expressed in units of minutes for the
454/// constructor of 'bdlt::DatetimeTz', but the class 'print' method shows that
455/// value as the concatenated decimal values four hours and minutes.
456///
457/// Next, since we prefer to hold celebrations on weekend days, not weekdays, we
458/// determine the day of the week on which the milestone date falls.
459///
460/// To aid our calculation, we define a 'bdlt::DayOfWeekSet' object set of the
461/// weekend days in New York City.
462/// @code
463/// bdlt::DayOfWeekSet weekendDays;
464/// weekendDays.add(bdlt::DayOfWeek::e_SATURDAY);
465/// weekendDays.add(bdlt::DayOfWeek::e_SUNDAY);
466/// @endcode
467/// Now, we determine if the target date is a weekend day. If so, we can plan our
468/// celebration for that date; otherwise, we will plan for the next weekend date.
469/// @code
470/// bdlt::Date milestone = dtz20kLocal.localDatetime().date();
471/// bdlt::Date holdDate = weekendDays.isMember(milestone.dayOfWeek())
472/// ? milestone
473/// : bdlt::DateUtil::nextDayOfWeek(
474/// bdlt::DayOfWeek::e_SATURDAY,
475/// milestone);
476/// @endcode
477/// Finally, we examine our results:
478/// @code
479/// bsl::cout << "Milestone:" << " "
480/// << milestone.dayOfWeek() << " "
481/// << milestone << bsl::endl;
482///
483/// bsl::cout << "Hold date:" << " "
484/// << holdDate.dayOfWeek() << " "
485/// << holdDate << bsl::endl;
486/// @endcode
487/// we find:
488/// @code
489/// Milestone: THU 03OCT2024
490/// Hold date: SAT 05OCT2024
491/// @endcode
492/// and we send out hold-the-date requests to our friends and family.
493///
494/// @}
495/** @} */