bdlt.txt @PURPOSE: Provide date and time vocabulary types, and related utilities. @MNEMONIC: Basic Development Library Time (bdlt) @DESCRIPTION: The 'bdlt' ("Basic Development Library Time") package provides vocabulary types for representing date, time, and datetime values, and utilities providing non-primitive functionality on the value types. Additional utilities provide: : o Current date, time, and local-time offset values. : o Conversion between different date and time representations. : o Arithmetic and validation functions See {Value Types} and {Utilities} below for overviews of the types and functions provided by this package. /Hierarchical Synopsis /--------------------- The 'bdlt' package currently has 40 components having 9 levels of physical dependency. The list below shows the hierarchical ordering of the components. The order of components within each level is not architecturally significant, just alphabetical. .. 9. bdlt_defaultcalendarcache bdlt_defaulttimetablecache 8. bdlt_calendarcache bdlt_timetablecache 7. bdlt_currenttime bdlt_fixutil bdlt_iso8601util 6. bdlt_calendarutil bdlt_datetimetz bdlt_localtimeoffset bdlt_timetableloader 5. bdlt_calendar bdlt_calendarloader bdlt_datetimeutil bdlt_datetz bdlt_epochutil bdlt_timetable 4. bdlt_datetime bdlt_dateutil bdlt_fuzzutil bdlt_packedcalendar bdlt_timetz bdlt_timeutil 3. bdlt_date bdlt_datetimeintervalutil bdlt_intervalconversionutil bdlt_time 2. bdlt_datetimeimputil bdlt_datetimeinterval bdlt_dayofweekset bdlt_dayofweekutil bdlt_serialdateimputil 1. bdlt_calendarreverseiteratoradapter bdlt_dayofweek bdlt_fixutilconfiguration bdlt_iso8601utilconfiguration bdlt_monthofyear bdlt_posixdateimputil bdlt_prolepticdateimputil bdlt_timeunitratio .. /Component Synopsis /------------------ : 'bdlt_calendar': : Provide fast repository for accessing weekend/holiday information. : : 'bdlt_calendarcache': : Provide an efficient cache for read-only 'bdlt::Calendar' objects. : : 'bdlt_calendarloader': : Provide a protocol (or pure interface) for loading calendars. : : 'bdlt_calendarreverseiteratoradapter': : Provide reverse iterator adapter for calendar iterators. : : 'bdlt_calendarutil': : Provide common date manipulations requiring a calendar. : : 'bdlt_currenttime': : Provide utilities to retrieve the current time. : : 'bdlt_date': : Provide a value-semantic type to represent dates. : : 'bdlt_datetime': : Provide a value-semantic type representing both date and time. : : 'bdlt_datetimeimputil': : Provide constants useful for encoding datetimes. : : 'bdlt_datetimeinterval': : Provide a representation of an interval of time. : : 'bdlt_datetimeintervalutil': : Provide non-primitive operations on 'bdlt::DatetimeInterval'. : : 'bdlt_datetimetz': : Provide a representation of a date and time with time zone offset. : : 'bdlt_datetimeutil': : Provide common non-primitive operations on 'bdlt::Datetime'. : : 'bdlt_datetz': : Provide a representation of a date with time zone offset. : : 'bdlt_dateutil': : Provide common non-primitive operations on date objects. : : 'bdlt_dayofweek': : Provide an enumeration of the set of days of the week. : : 'bdlt_dayofweekset': : Provide an ordered set of (unique) 'bdlt::DayOfWeek::Enum' values. : : 'bdlt_dayofweekutil': : Provide common non-primitive operations on 'bdlt::DayOfWeek::Enum'. : : 'bdlt_defaultcalendarcache': : Provide a process-wide default 'bdlt::CalendarCache' object. : : 'bdlt_defaulttimetablecache': : Provide a process-wide default 'bdlt::TimetableCache' object. : : 'bdlt_epochutil': : Conversion between absolute/relative time with respect to epoch. : : 'bdlt_fixutil': : Provide conversions between date/time objects and FIX strings. : : 'bdlt_fixutilconfiguration': : Provide an attribute class to configure FIX string generation. : : 'bdlt_fuzzutil': : Provide creation of 'bdlt' data types from fuzz data. : : 'bdlt_intervalconversionutil': : Provide functions to convert between time-interval representations. : : 'bdlt_iso8601util': : Provide conversions between date/time objects and ISO 8601 strings. : : 'bdlt_iso8601utilconfiguration': : Provide an attribute class to configure ISO 8601 string generation. : : 'bdlt_localtimeoffset': : Provide utilities to retrieve the local time offset. : : 'bdlt_monthofyear': : Enumerate the set of month-of-year values. : : 'bdlt_packedcalendar': : Provide a compact repository for weekend/holiday information. : : 'bdlt_posixdateimputil': : Provide low-level support functions for date-value manipulation. : : 'bdlt_prolepticdateimputil': : Provide low-level support functions for date-value manipulation. : : 'bdlt_serialdateimputil': : Provide low-level support functions for date-value manipulation. : : 'bdlt_time': : Provide a value-semantic type representing time-of-day. : : 'bdlt_timetable': : Provide a repository for accessing timetable information. : : 'bdlt_timetablecache': : Provide an efficient cache for read-only 'bdlt::Timetable' objects. : : 'bdlt_timetableloader': : Provide a protocol (or pure interface) for loading timetables. : : 'bdlt_timetz': : Provide a representation of a time with time zone offset. : : 'bdlt_timeunitratio': : Provide constants characterizing ratios between common time units. : : 'bdlt_timeutil': : Provide common non-primitive operations on 'bdlt::Time'. /Value Types /----------- This package defines value-semantic types that represent dates, times (of day), and combined date and time values. For each of these "time" types, there is a related type that also holds a time offset value from UTC. There are also enumerated types representing the months of the year and the days of the week. /Value Types: 'Date', 'Time' and 'Datetime' / - - - - - - - - - - - - - - - - - - - - - The 'bdlt' package defines 'bdlt::Date' to represent date values, 'bdlt::Time' to represent time values (to microsecond resolution) within a day, and the combined 'bdlt::Datetime' to represent all points in time (to microsecond resolution) across the range of date values. The ranges of each type are shown below. .. Type Range ------- ------------------------------------------------------------ Date [0001/01/01 .. 9999/12/31 ] Time [ 00:00:00.000000 .. 23:59:59.999999 ] Datetime [0001/01/01_00:00:00.000000 .. 9999/12/31_23:59:59.999999 ] .. Further note that: : o The date values follow the Unix (POSIX) calendar (see {'bdlt_date'}. : o The definition of 'bdlt::Datetime' does *not* allow for leap seconds. The above classes define values representing points on a timeline (e.g., dates on a calendar, positions on a clock) whereas the 'bdlt::DatetimeInterval' class represents the *difference* (to microsecond resolution) between those points. .. Type Difference Type ------- ---------------- Date int (days) Time DatetimeInterval Datetime DatetimeInterval DatetimeInterval DatetimeInterval .. Each of these classes are designed to hold date and time values, but do not themselves provide means for obtaining values such as current time and date. Those values are available via separate utility components. See {Obtaining Current Date, Time, and Local-Time Offset Values}. /Singular 'Time' and 'Datetime' Values /- - - - - - - - - - - - - The 'bdlt::Time' class defines a singular value, "24:00:00.000000", which is also the default-constructed value. This singular value is distinguished in two ways: : o Relational comparisons to other time values are disallowed -- the behavior : is undefined. Note that comparisons of equality and inequality to other : values *are* legal. : : o Note that the singular value cannot appear as a key value in any of the : standard ordered containers (which require weak ordering of keys). : : o The singular value is implicitly converted to "00:00:00.000000" (midnight) : in arithmetic operations using 'bdlt::Time' values. Similarly, the 'bdlt::Datetime' class defines one singular value, "0001/01/01_24:00:00.000000", which happens to be the default constructed value. The restrictions and semantics of this value parallel those of the singular 'bdlt::Time' value. Some applications use the singular values of these types as placeholders when a value must be provided but is not known. (See 'bdetu_unset'.) /Timezone Augmented Value Types: 'DateTz', 'TimeTz' and 'DatetimeTz' /- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - For each of the basic date and time types there is a corresponding value-semantic type that is augmented with a value representing an offset (in minutes) from UTC. Note that other BDE types represent local time offset as seconds (e.g., the 'seconds' attribute of 'bsls::TimeInterval'). The local time offset augmented types are: .. Basis Type Augmented Type ---------- ---------------- bldt:Date bdlt::DateTz bldt:Time bdlt::TimeTz bldt:Datetime bdlt::DatetimeTz .. These types are not normalized to a common time zone when they are compared, hence, equality between objects of any of these types requires that the object have both the same local time and the same local-time offset values. To determine *equivalence* between such objects, each of these classes provides a 'utc*' accessor method. These types themselves do not validate that the combinations of dates, times, and local-time offset values they hold correspond to a valid time in any officially recognized time zone. See {Obtaining Current Date, Time, and Local-Time Offset Values}. /Enumerated Values /- - - - - - - - - The 'bdlt' package provides enumerations in 'bdlt_monthofyear' and 'bdlt_dayofweek'. The 'bdlt_dayofweekset' provides an efficient, ordered container of unique 'btdl::DayofWeek::Enum' values (i.e., containing no more than seven elements). /Utilities /--------- This package provides utility components that: : o Provide current date, time, and local-time offset values. : o Provide date arithmetic functions. : o Provide a wide variety of conversion methods: between the value types : defined in this package, between the package value types and standard types : for date and time, between time values in different standard units (e.g., : hours, minutes, nanoseconds). /Obtaining Current Date, Time, and Local-Time Offset Values / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The 'bdlt_currenttime' component provides: : o A 'bdlt::Datetime' value for the current UTC time. : o A 'bdlt::Datetime' value for the current local time. : o A 'bsls::TimeInterval' from the start of the epoch. The 'bdlt_localtimeoffset' component defines a function that returns the offset of the host machines designated time zone (as set by the system administrator) from UTC, including adjustments between standard and daylight-saving time, as of a given UTC time and date. For local-time offset for arbitrary time zones see the {'baetzo'} package. Both 'bdlt::CurrentTime' and 'bdlt::LocalTimeOffset' obtain their values via user-installed callback functions. The default callbacks obtain their values from platform appropriate system calls. User-defined callbacks can provide high-performance (e.g., cached) alternatives to the default system calls, can be instrumented to gather statistics, and can simulate the passage of time for test scenarios. /Advanced Date Arithmetic: 'bdlt::DateUtil' / - - - - - - - - - - - - - - - - - - - - - The 'bdet_dateutil' component provides functions on 'bdlt::Date' values that extend those provided by the 'bdlt::Date' class itself. For example: : o Calculate the 'bdlt::Date' that is a specified number of months -- or years : -- before or after a given date. Two different end-of-month conventions : are provided. : : o Find the next -- or previous -- occurrence of a given day of week relative : to a specified date (inclusive or exclusive of that specified date). : : o Find the date of a specified day of week that is the *nth* (e.g., 1st, 3rd) : or last occurrence in a specified year and month. This utility also provides a function for conversion of 'bdlt::Date' values to and from 'int' values in the "YYYYMMDD" format. /Conversion of 'Date', 'Time' and 'Datetime' Values / - - - - - - - - - - - - - - - - - - - - - - - - - Several utility components of 'bdlt' provide functions for the conversion of date and time types to other types, some defined in the C++ Standard, others defined elsewhere in BDE. In particular, the 'bdlt_epochutil' component provides functions that convert 'bdlt::Datetime' values (in UTC) -- understood to represent an absolute date and time in UTC -- to equivalent difference values measured from the start of the Unix standard epoch (1970/01/01_00:00:00.000000 UTC). .. Component Conversions ----------------- -------------------------------------------------------- bdlt_dateutil bdlt::Date <=> 'int' in "YYYYMMDD" format bdlt_datetimeutil bdlt::Datetime <=> bsl::tm bdlt_epochutil bdlt::Datetime <=> bsl::time_t from the epoch bdlt::Datetime <=> bdlt::TimeT64 from the epoch bdlt::Datetime <=> bsls::TimeInterval from the epoch bdlt::Datetime <=> bdlt::DateTimeInterval from the epoch bdlt_intervalconversionutil bdlt::DatetimeInterval <=> bsls::TimeInterval bdlt_serialdateimputil bdlt::Date <=> 'int' in the range '[1 .. 3652059]' (corresponding to '[00001/01/01 .. 9999/12/31]') .. /Conversion of Conventional Time Units /- - - - - - - - - - - - - - - - - - - The 'bdlt_timeunitratio' component provides a set of constants that express the ratios between standard time units such as days, hours, ..., nanoseconds. One example is 'bdlt::TimeUnitRatio::k_MILLISECONDS_PER_MINUTE'. /Usage /----- This section illustrates intended use of these components. /Example 1: Celebrating Milestone Dates / - - - - - - - - - - - - - - - - - - - Date and time calculations are simple in principle but tedious and error- prone in practice. Consequently, people tend to schedule events on dates that are easy to calculate -- e.g., first of the month, anniversary dates -- even though we know that not all months and years express intervals of the same length. Access to a rich set of types and utilities for date and time calculations affords us other options. Suppose we wish to commemorate the 20,000th day since our birth. First, create a 'bdlt::Datetime' object to represent our date of birth. Let us assume that we were born at the exact start of the Unix epoch: .. bdlt::Datetime dtBirthday = bdlt::EpochUtil::epoch(); assert(bdlt::Datetime(1970, 1, 1, 0, 0, 0, 0) == dtBirthday); .. Next, we calculate the milestone date (and time). .. bdlt::Datetime dt20k(dtBirthday); dt20k.addDays(20000); assert(bdlt::DatetimeInterval(20000) == dt20k - dtBirthday); bsl::cout << dt20k << bsl::endl; .. and find: .. 04OCT2024_00:00:00.000000 .. The above value represents UTC date and time values. We, however, plan to celebrate the milestone in New York City. Thus, we must obtain the local time offset in NYC for that future date and use it to calculate the milestone (date) in that time zone. .. bsls::TimeInterval localTimeOffset = bdlt::LocalTimeOffset::localTimeOffset(dt20k); bdlt::DatetimeInterval dtOffset = bdlt::IntervalConversionUtil::convertToDatetimeInterval(localTimeOffset); bdlt::DatetimeTz dtz20kLocal( dt20k + dtOffset, static_cast<int>(dtOffset.totalMinutes())); bsl::cout << dtz20kLocal << bsl::endl; .. which is one calendar day earlier: .. 03OCT2024_20:00:00.000000-0400 .. Notice that the local time offset was expressed in units of minutes for the constructor of 'bdlt::DatetimeTz', but the class 'print' method shows that value as the concatenated decimal values four hours and minutes. Next, since we prefer to hold celebrations on weekend days, not weekdays, we determine the day of the week on which the milestone date falls. To aid our calculation, we define a 'bdlt::DayOfWeekSet' object set of the weekend days in New York City. .. bdlt::DayOfWeekSet weekendDays; weekendDays.add(bdlt::DayOfWeek::e_SATURDAY); weekendDays.add(bdlt::DayOfWeek::e_SUNDAY); .. Now, we determine if the target date is a weekend day. If so, we can plan our celebration for that date; otherwise, we will plan for the next weekend date. .. bdlt::Date milestone = dtz20kLocal.localDatetime().date(); bdlt::Date holdDate = weekendDays.isMember(milestone.dayOfWeek()) ? milestone : bdlt::DateUtil::nextDayOfWeek( bdlt::DayOfWeek::e_SATURDAY, milestone); .. Finally, we examine our results: .. bsl::cout << "Milestone:" << " " << milestone.dayOfWeek() << " " << milestone << bsl::endl; bsl::cout << "Hold date:" << " " << holdDate.dayOfWeek() << " " << holdDate << bsl::endl; .. we find: .. Milestone: THU 03OCT2024 Hold date: SAT 05OCT2024 .. and we send out hold-the-date requests to our friends and family.