Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdlt_datetimetz
[Package bdlt]

Provide a representation of a date and time with time zone offset. More...

Namespaces

namespace  bdlt

Detailed Description

Outline
Purpose:
Provide a representation of a date and time with time zone offset.
Classes:
bdlt::DatetimeTz local-datetime value with time zone offset from UTC
See also:
Component bdlt_datetime
Description:
This component provides a single value-semantic class, bdlt::DatetimeTz, that represents a datetime value in a particular time zone. Each bdlt::DatetimeTz object contains a time zone offset from UTC (in minutes) and a bdlt::Datetime value in that time zone. For logical consistency, the datetime value and offset should correspond to a geographically valid time zone, but such consistency is the user's responsibility. This component does not enforce logical constraints on any values.
Caveats on Time Zone Support:
A bdlt::DatetimeTz value is intended to be interpreted as a value in a local time zone, along with the offset of that value from UTC. However, there are some problems with this simple interpretation. First of all, the offset value may not correspond to any time zone that has ever existed. For example, the offset value could be set to one minute, or to 1,234 minutes. The meaning of the resulting "local datetime" value is always clear, but the local datetime might not correspond to any geographical or historical time zone.
The second problem is more subtle. A given offset from UTC might be "valid" in that it corresponds to a real time zone, but the actual datetime value might not exist in that time zone. To make matters worse, a "valid" offset may not (indeed, rarely will) specify one time zone uniquely. Moreover, the datetime value might be valid in one time zone corresponding to a given offset, and not in another time zone.
For these reasons (and others), this component cannot and does not perform any validation relating to time zones or offsets. The user must take care to honor the "local datetime" contract of this component.
ISO Standard Text Representation:
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.
Usage:
This section illustrates intended use of this component.
Example 1: Basic bdlt::DatetimeTz Usage:
This example demonstrates how to create and use a bdlt::DatetimeTz object.
First, create an object dt1 having the default value, and then verify that it contains an offset of 0, implying that the object represents a date and time in the UTC time zone, and the value of the datetime is the same as that of a default constructed bdlt::Datetime object:
  bdlt::DatetimeTz dt1;
  assert(0                == dt1.offset());
  assert(bdlt::Datetime() == dt1.localDatetime());
Then, set dt1 to the value 12:00 noon (12:00:00.000) on 12/31/2005 in the EST time zone (UTC-5):
  bdlt::Datetime datetime1(2005, 12, 31, 12, 0, 0, 0);
  bdlt::Datetime datetime2(datetime1);
  int            offset1 = -5 * 60;

  dt1.setDatetimeTz(datetime1, offset1);
  assert(offset1             == dt1.offset());
  assert(dt1.localDatetime() != dt1.utcDatetime());
  assert(datetime1           == dt1.localDatetime());
  assert(datetime2           != dt1.utcDatetime());

  datetime2.addMinutes(-offset1);
  assert(datetime2 == dt1.utcDatetime());
Next, create dt2 as a copy of dt1:
  bdlt::DatetimeTz dt2(dt1);
  assert(offset1   == dt2.offset());
  assert(datetime1 == dt2.localDatetime());
  assert(datetime2 == dt2.utcDatetime());
Now, create a third object, dt3, representing the time 10:33:25.000 on 01/01/2001 in the PST time zone (UTC-8):
  bdlt::Datetime datetime3(2001, 1, 1, 10, 33, 25, 0);
  bdlt::Datetime datetime4(datetime3);
  int            offset2 = -8 * 60;

  bdlt::DatetimeTz dt3(datetime3, offset2);
  assert(offset2             == dt3.offset());
  assert(dt3.localDatetime() != dt3.utcDatetime());
  assert(datetime3           == dt3.localDatetime());
  assert(datetime4           != dt3.utcDatetime());

  datetime4.addMinutes(-offset2);
  assert(datetime4 == dt3.utcDatetime());
Finally, stream the values of dt1, dt2, and dt3 to stdout:
  bsl::cout << dt1 << bsl::endl
            << dt2 << bsl::endl
            << dt3 << bsl::endl;
The streaming operator produces the following output on stdout:
  31DEC2005_12:00:00.000-0500
  31DEC2005_12:00:00.000-0500
  01JAN2001_10:33:25.000-0800
Example 2: Delivery Estimation System:
Let us suppose that we are implementing a delivery estimation system for a shipping company. The system provides estimated delivery dates and times of client shipments. This information is provided in the local time zone and is represented as a bdlt::DatetimeTz object. Below is the definition for a struct that returns the estimated delivery date.
                       // =====================
                       // struct DeliverySystem
                       // =====================

  struct DeliverySystem {
      // This struct provides a function that returns the estimated delivery
      // date and time for a particular shipment.

      // PRIVATE CLASS METHODS
      static bdlt::Datetime getCurrentUTCDatetime();
          // Return the current UTC date and time.

    public:
      // TYPES
      enum City {
          // This enumeration provides an identifier for the various cities.

          e_CHICAGO = 0,
          e_DUBAI,
          e_NEW_YORK,
          e_LONDON,
          e_LOS_ANGELES
      };

      // CLASS METHODS
      static bdlt::DatetimeTz getEstimatedDeliveryDatetime(City city);
          // Return the estimated delivery date and time, in local time, for
          // a shipment being sent to the specified 'city'.
  };
All the relevant data used for delivery estimation is stored in a lookup table as shown below:
  const int k_MINUTES_PER_HOUR = 60;

  static const struct {
      int d_offset;         // time zone offset from UTC (in minutes)
      int d_deliveryTime;   // delivery time (in minutes)
  } DATA[] = {
   //    Offset                   DeliveryTime
   //    =======================  =======================
   {     -6 * k_MINUTES_PER_HOUR, 10 * k_MINUTES_PER_HOUR  },  // Chicago
   {      3 * k_MINUTES_PER_HOUR, 72 * k_MINUTES_PER_HOUR  },  // Dubai
   {     -5 * k_MINUTES_PER_HOUR,      k_MINUTES_PER_HOUR  },  // New York
   {          k_MINUTES_PER_HOUR, 36 * k_MINUTES_PER_HOUR  },  // London
   {     -8 * k_MINUTES_PER_HOUR, 24 * k_MINUTES_PER_HOUR  },  // Los Angeles
  };
And here are the function definitions:
                       // ---------------------
                       // struct DeliverySystem
                       // ---------------------

  // PRIVATE CLASS METHODS
  bdlt::Datetime DeliverySystem::getCurrentUTCDatetime()
  {
      // Return a fixed datetime so that output is known a priori.
      return bdlt::Datetime(2014, 10, 17, 14, 48, 56);
  }

  // CLASS METHODS
  bdlt::DatetimeTz DeliverySystem::getEstimatedDeliveryDatetime(City city)
  {
      bdlt::Datetime localDatetime(getCurrentUTCDatetime());
      localDatetime.addMinutes(DATA[city].d_offset
                             + DATA[city].d_deliveryTime);
      return bdlt::DatetimeTz(localDatetime, DATA[city].d_offset);
  }
When we print out the delivery times:
  bsl::cout << "Estimated Delivery Time in Chicago:     "
            << DeliverySystem::getEstimatedDeliveryDatetime(
                                                   DeliverySystem::e_CHICAGO)
            << bsl::endl;
  bsl::cout << "Estimated Delivery Time in Dubai:       "
            << DeliverySystem::getEstimatedDeliveryDatetime(
                                                     DeliverySystem::e_DUBAI)
            << bsl::endl;
  bsl::cout << "Estimated Delivery Time in New York:    "
            << DeliverySystem::getEstimatedDeliveryDatetime(
                                                  DeliverySystem::e_NEW_YORK)
            << bsl::endl;
  bsl::cout << "Estimated Delivery Time in London:      "
            << DeliverySystem::getEstimatedDeliveryDatetime(
                                                    DeliverySystem::e_LONDON)
            << bsl::endl;
  bsl::cout << "Estimated Delivery Time in Los Angeles: "
            << DeliverySystem::getEstimatedDeliveryDatetime(
                                               DeliverySystem::e_LOS_ANGELES)
            << bsl::endl;
We get the following results:
  Estimated Delivery Time in Chicago:     17OCT2014_18:48:56.000-0600
  Estimated Delivery Time in Dubai:       20OCT2014_17:48:56.000+0300
  Estimated Delivery Time in New York:    17OCT2014_10:48:56.000-0500
  Estimated Delivery Time in London:      19OCT2014_03:48:56.000+0100
  Estimated Delivery Time in Los Angeles: 18OCT2014_06:48:56.000-0800