Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component baltzo_zoneinfocache
[Package baltzo]

Provide a cache for time-zone information. More...

Namespaces

namespace  baltzo

Detailed Description

Outline
Purpose:
Provide a cache for time-zone information.
Classes:
baltzo::ZoneinfoCache a cache for time-zone information
See also:
Component baltzo_zoneinfo, Component baltzo_defaultzoneinfocache
Description:
This component defines a class, baltzo::ZoneinfoCache, that serves as a cache of baltzo::Zoneinfo objects. A time-zone cache is supplied, on construction, with a baltzo::Loader object to obtain time-zone information objects from some data source. Invocation of the getZoneinfo method for a specified time zone returns the address of either previously cached data, or if that data is not cache-resident, a new loaded baltzo::Zoneinfo object, which is cached for use in subsequent calls to getZoneinfo and lookupZoneinfo. Addresses returned by either of these methods are valid for the lifetime of the cache.
Thread Safety:
baltzo::ZoneinfoCache is fully thread-safe, meaning that all non-creator operations on an object can be safely invoked simultaneously from multiple threads.
Usage:
In this section, we demonstrate creating a baltzo::ZoneinfoCache object and using it to access time zone information.
Example 1: Creating a Concrete baltzo::Loader:
A baltzo::ZoneinfoCache object is provided a baltzo::Loader on construction. The loader is used to populate the cache per user requests via the getZoneinfo method. In this example, we use a TestLoader implementation of the baltzo::Loader protocol, based on the baltzo_testloader component. In this example, our test loader is explicitly primed with responses for requests for certain time-zone identifiers. Note that, in practice, a loader typically obtains time-zone information from some external data store (e.g., see baltzo_datafileloader).
We start by creating and initializing a couple of example time zone information objects. Note that the baltzo::Zoneinfo objects below are illustrative, and contain no actual time zone information:
  baltzo::Zoneinfo newYorkZoneinfo;
  newYorkZoneinfo.setIdentifier("America/New_York");

  baltzo::Zoneinfo londonZoneinfo;
  londonZoneinfo.setIdentifier("Europe/London");
Next we create a description of Eastern Standard Time (EST) and Greenwich Mean Time (GMT):
  baltzo::LocalTimeDescriptor est(-5 * 60 * 60, false, "EST");
  baltzo::LocalTimeDescriptor gmt(           0, false, "GMT");
Then we set the initial transition for newYorkZoneinfo to Eastern Standard Time, and the initial transition for londonZoneinfo to Greenwich Mean Time. Note that such an initial transition is required for a baltzo::Zoneinfo object to be considered Well-Formed (see isWellFormed):
  bsls::Types::Int64 firstTime = bdlt::EpochUtil::convertToTimeT64(
                                                    bdlt::Datetime(1, 1, 1));
  newYorkZoneinfo.addTransition(firstTime, est);
  londonZoneinfo.addTransition(firstTime, gmt);
Next we create a TestLoader, and then populate it with our example time zone information objects:
  TestLoader testLoader;
  testLoader.setTimeZone(newYorkZoneinfo);
  testLoader.setTimeZone(londonZoneinfo);
Finally, we verify that testLoader contains the configured baltzo::Zoneinfo objects for New York and London:
  baltzo::Zoneinfo newYorkResult;
  int rc = testLoader.loadTimeZone(&newYorkResult, "America/New_York");
  assert(0 == rc);
  assert(newYorkZoneinfo == newYorkResult);

  baltzo::Zoneinfo londonResult;
  rc = testLoader.loadTimeZone(&londonResult, "Europe/London");
  assert(0 == rc);
  assert(londonZoneinfo == londonResult);
Example 2: Creating and Using a baltzo::ZoneinfoCache:
In this example, we create a baltzo::ZoneinfoCache, and use it to access time zone information for several time zones.
We start by creating a baltzo::ZoneinfoCache object supplied with the address of the TestLoader we populated in the preceding example:
  baltzo::ZoneinfoCache cache(&testLoader);
Next, we verify the newly constructed cache does not contain either New York or London:
  assert(0 == cache.lookupZoneinfo("America/New_York"));
  assert(0 == cache.lookupZoneinfo("Europe/London"));
Then, we call getZoneinfo to obtain the data for the New York time zone. Note that, because this is the first getZoneinfo operation on the class, the time-zone data has not previously been retrieved, and the data must be loaded using the loader supplied at construction:
  const baltzo::Zoneinfo *newYork = cache.getZoneinfo(&rc,
                                                      "America/New_York");

  assert(0 == rc);
  assert(0 != newYork);
  assert("America/New_York" == newYork->identifier());
Next, we verify that a subsequent call lookupZoneinfo for New York, returns the previously cached value. However, a call to lookupZoneinfo for London will return 0 because the value has not been cached:
  assert(newYork == cache.lookupZoneinfo("America/New_York"));
  assert(0       == cache.lookupZoneinfo("Europe/London"));
Next, we call getZoneinfo for London and verify that it returns the expected value:
  const baltzo::Zoneinfo *london = cache.getZoneinfo(&rc, "Europe/London");
  assert(0 == rc);
  assert(0 != london);
  assert("Europe/London" == london->identifier());
Finally, we call getZoneinfo with time zone identifier unknown to our TestLoader. The call to getZoneinfo returns 0 because the time zone information cannot be loaded. Examination of rc shows indicates that the identifier is not supported:
  assert(0 == cache.getZoneinfo(&rc, "badId"));
  assert(baltzo::ErrorCode::k_UNSUPPORTED_ID == rc);