BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt_datetimetz

Detailed Description

Outline

Purpose

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

Classes

See also
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:

assert(0 == dt1.offset());
assert(bdlt::Datetime() == dt1.localDatetime());
Definition bdlt_datetimetz.h:308
Datetime localDatetime() const
Definition bdlt_datetimetz.h:660
int offset() const
Definition bdlt_datetimetz.h:666
Definition bdlt_datetime.h:331

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());
void setDatetimeTz(const Datetime &localDatetime, int offset)
Definition bdlt_datetimetz.h:602
Datetime utcDatetime() const
Definition bdlt_datetimetz.h:678

Next, create dt2 as a copy of 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
// =====================
/// This struct provides a function that returns the estimated delivery
/// date and time for a particular shipment.
struct DeliverySystem {
// PRIVATE CLASS METHODS
/// Return the current UTC date and time.
static bdlt::Datetime getCurrentUTCDatetime();
public:
// TYPES
/// This enumeration provides an identifier for the various cities.
enum City {
e_CHICAGO = 0,
e_DUBAI,
e_NEW_YORK,
e_LONDON,
e_LOS_ANGELES
};
// CLASS METHODS
/// Return the estimated delivery date and time, in local time, for
/// a shipment being sent to the specified `city`.
static bdlt::DatetimeTz getEstimatedDeliveryDatetime(City 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