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