Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component baltzo_zoneinfo
[Package baltzo]

Provide a value type to represent a time zone. More...

Namespaces

namespace  baltzo

Detailed Description

Outline
Purpose:
Provide a value type to represent a time zone.
Classes:
baltzo::Zoneinfo information about a time zone
baltzo::ZoneinfoTransition attributes representing a time transition
See also:
Component baltzo_localtimedescriptor, Component baltzo_zoneinfoutil
Description:
This component provides a value semantic type, baltzo::Zoneinfo, that represents the information about a specific time zone contained in the Zoneinfo database. In addition, this component provides an unconstrained in-core value-semantic type baltzo::ZoneinfoTransition that can be used to characterize a transition for time zones.
baltzo::ZoneinfoTransition:
A baltzo::ZoneinfoTransition contains:
  Name        Type
  ----------  --------------------------
  utcTime     bdlt::EpochUtil::TimeT64
  descriptor  baltzo::LocalTimeDescriptor
  • utcTime: UTC time when a transition occurs
  • descriptor: local time value corresponding to the time transition
For example, in New York on March 14, 2011, at the instant 1 a.m., clocks are set forward by an hour to mark the transition from Eastern Standard Time to Eastern Daylight Time. This change can be represented by a baltzo::ZoneinfoTransition object whose utcTime refers to March 14, 2011, 1am and whose descriptor describes Eastern Daylight Time (i.e., description is "EDT", dstInEffectFlag is true, and utcOffsetInSeconds is -14,400 (-4 * 60 * 60)).
baltzo::Zoneinfo:
A baltzo::Zoneinfo contains:
  • the time zone identifier (e.g., "America/New_York" or "Asia/Tokyo")
  • the ordered sequence of baltzo::ZoneinfoTransition objects, representing the various transitions from UTC for this time zone.
  • an optional POSIX-like TZ environment string used to represent far-reaching times past the end of the explicit time zone data.
A baltzo::Zoneinfo object also provides the method findTransitionForUtcTime that allows a client to find, in the sequence of transitions, the appropriate transition whose local-time descriptor describes the properties of local time, at a specified UTC time, for the time zone in question. Note that, even though this information is sufficient for converting local date and time, to their corresponding values in other time zones, clients are encouraged to use the utilities provided in baltzo_timezoneutil. Also note that, baltzo::Zoneinfo objects are typically populated by the client through the baltzo::Loader protocol, and not directly.
Zoneinfo Database:
This database, also referred to as either the TZ database or the Olson database (after its creator, Arthur Olson), is a standard, public-domain time-zone information distribution used by many software systems (including a number of Unix variants and the Java Runtime Environment). Information about the Zoneinfo database -- including the time zone rules for the supported time zones, and source code for the zic compiler (for compiling those rules into the binary representation used by this component) -- can be found online at http://www.iana.org/time-zones/repository/tz-link.html. This time zone information can be used to perform the conversion of dates and times from UTC to their corresponding dates and times in a given time zone and vice-versa. (See baltzo_zoneinfobinaryreader for more information about the binary file format.)
posixExtendedRangeDescription:
This string may be populated with a POSIX-like TZ string that describes rules for local time are handled before the first and after the last local-time transitions maintained by this object. Typically this is used for computing local time values far in the future. The rules for the encoded string can be found online at http://www.ibm.com/developerworks/aix/library/au-aix-posix/.
Usage:
The following usage examples illustrate how to populate a baltzo::Zoneinfo object and use it to transform a UTC time into a local time.
Example 1: Populate a baltzo::Zoneinfo:
Suppose we want to represent the time-zone information for New York, in 2010 using a baltzo::Zoneinfo object. In order to do so, we need to provide the UTC date-times (transitions) after which the time zone changes its offset from UTC, or daylight-saving Time starts or ends.
First, we define two times "Mar 14, 2010 6:00 AM" and "Nov 07, 2010 7:00 AM" representing respectively the UTC time at which New York transitions to Eastern Daylight-saving Time (EDT) and Eastern Standard Time (EST) in 2010:
  bdlt::Datetime edtDatetime(2010, 03, 14, 2, 0);
  bdlt::Datetime estDatetime(2010, 11, 07, 2, 0);
Then, we create two local-time descriptors that hold the offset from UTC and DST status for EST and EDT in New York in 2010, in terms of their offsetFromUtcInSeconds, dstInEffectFlag and description attributes:
  const baltzo::LocalTimeDescriptor est(-5 * 60 * 60, false, "EST");
  const baltzo::LocalTimeDescriptor edt(-4 * 60 * 60, true,  "EDT");
Note that these descriptors will be associated with the created transition times, to reflect how local time in New York changes its offset from UTC and DST status after specific times.
Next, we create an empty baltzo::Zoneinfo object that will be populated with the information necessary to describe the time zone for New York:
  baltzo::Zoneinfo newYorkTimeZone;
Then, before being able to associate the transition times with their corresponding descriptors, we need translate the transition times to bdlt::EpochUtil::TimeT64: Now, we associate the created descriptors with the transitions we indicated previously and add them to newYorkTimeZone using the addTransition method:
  newYorkTimeZone.addTransition(edtTransitionTime, edt);
  newYorkTimeZone.addTransition(estTransitionTime, est);
Note that this insertion operation maintains the transitions in order of transition time, and therefore inserting transitions out-of-order, while not illegal, is very inefficient.
Finally we verify that the newYorkTimeZone contains the transitions we indicated:
  {
      baltzo::Zoneinfo::TransitionConstIterator it =
                                          newYorkTimeZone.beginTransitions();

      assert(it->utcTime()    == edtTransitionTime);
      assert(it->descriptor() == edt);
      ++it;
      assert(it->utcTime()    == estTransitionTime);
      assert(it->descriptor() == est);
  }
Notice that the iterator refers to a baltzo::ZoneinfoTransition object.
Example 2: Converting UTC to Local Time:
Suppose that we want to program a function, utcToLocalTime to perform the conversion from a UTC time value to the corresponding local time value, in a given time zone, and return the computed local time:
First we declare the function utcToLocalTime and its contract:
  static bdlt::DatetimeTz utcToLocalTime(const bdlt::Datetime&   utcTime,
                                        const baltzo::Zoneinfo& timeZone)
  {
      // Return the 'bdlt::DatetimeTz' value representing the date, time and
      // offset from UTC (rounded to the minute) value of the local time,
      // corresponding to the specified 'utcTime' in the specified
      // 'timeZone'.  The behavior is undefined if the 'utcTime' precedes the
      // time of the first transition contained in 'timeZone' and
      // '0 < timeZone.numTransitions()'.
Then, we check the precondition of utcToLocalTime, by checking that timeZone contains at least one transitions and comparing utcTime to the first transition time in timeZone:
      BSLS_ASSERT(0 < timeZone.numTransitions());
      BSLS_ASSERT(timeZone.firstTransition().utcTime() <=
                                 bdlt::EpochUtil::convertToTimeT64(utcTime));
Next, we obtain the appropriate baltzo::ZoneinfoTransition object, invoking the method findTransitionForUtcTime on timeZone: Then, we access the descriptor associated with the transition to which it refers, and calculate the offset from UTC rounded to the minute:
      const baltzo::ZoneinfoTransition& transition = *it;
      const int offsetInMinutes =
                           transition.descriptor().utcOffsetInSeconds() / 60;
Now, we apply the obtained offsetInMinutes to the originally specified utcTime obtaining the corresponding local time in the specified timeZone:
      bdlt::Datetime temp(utcTime);
      temp.addMinutes(offsetInMinutes);
Finally, return the local time value together with its offset from UTC:
      return bdlt::DatetimeTz(temp, offsetInMinutes);
  }
Suppose, now, we want to convert UTC time to the corresponding local time in New York. We can do so using the previously defined function utcToLocalTime and reusing the baltzo::Zoneinfo object, newYorkTimeZone of Example 1.
First, we define bdlt::Datetime object representing the UTC time "Apr 10, 2010 12:00":
  bdlt::Datetime utcDatetime(2010, 04, 10, 12, 0, 0);
Then, we invoke utcToLocalTime passing newYorkTimeZone as a time zone and save the result:
  bdlt::DatetimeTz nyDatetime = utcToLocalTime(utcDatetime, newYorkTimeZone);
Finally, we compute the New York local time corresponding to utcDatetime, verify that "April 10, 2010 8:00" is the computed time:
  const bdlt::Datetime expectedTime(2010, 4, 10, 8, 0, 0);
  assert(-4 * 60      == nyDatetime.offset());
  assert(expectedTime == nyDatetime.localDatetime());