// baltzo_timezoneutilimp.h -*-C++-*- #ifndef INCLUDED_BALTZO_TIMEZONEUTILIMP #define INCLUDED_BALTZO_TIMEZONEUTILIMP #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Implement utilities for converting times between time zones. // //@CLASSES: // baltzo::TimeZoneUtilImp: implementation utilities for converting times // //@SEE_ALSO: baltzo_localdatetime, baltzo_zoneinfo, // baltzo_defaultzoneinfocache // //@DESCRIPTION: This component provides a namespace, 'baltzo::TimeZoneUtilImp', // containing a set of utility functions for converting time values to and // from, their corresponding local time representations in (possibly) different // time zones. The primary methods provided include: 'convertUtcToLocalTime' // for converting time values to their corresponding local-time values in some // time zone; 'convertLocalToUtc', for converting a local-time value into the // corresponding UTC time value; and 'initLocalTime' for initializing a // local-time value. Additionally the 'loadLocalTimeForUtc' method enable // clients to obtain information about a time value, such as whether the // provided time is a daylight-saving time value. // ///Usage ///----- // The following examples demonstrate how to use a 'baltzo::TimeZoneUtilImp' to // perform common operations on time values: // ///Prologue: Initializing an Example 'baltzo::ZoneinfoCache' Object /// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Before using the methods provided by 'baltzo::TimeZoneUtilImp' we must first // define a 'baltzo::ZoneinfoCache' object containing information about various // time zones. For the purposes of this example, we will define a sample cache // containing only data for New York loaded through a 'baltzo::TestLoader' // object. Note that, in general, clients should use data from an external // data source (see 'baltzo_datafileloader'). // // First, we create a Zoneinfo object for New York, and populate 'newYork' with // a correct time zone identifier: //.. // baltzo::Zoneinfo newYork; // newYork.setIdentifier("America/New_York"); //.. // Next, we create two local-time descriptors, one for standard time and one // for daylight-saving time: //.. // baltzo::LocalTimeDescriptor est(-18000, false, "EST"); // baltzo::LocalTimeDescriptor edt(-14400, true, "EDT"); //.. // Then, we set the initial descriptor for 'newYork' to Eastern Standard Time. // Note that such an initial transition is required for a 'baltzo::Zoneinfo' // object to be considered Well-Defined (see 'baltzo_zoneinfoutil') //.. // const bsls::Epoch::TimeT64 firstTransitionTime = // bdlt::EpochUtil::convertToTimeT64(bdlt::Datetime(1, 1, 1)); // // newYork.addTransition(firstTransitionTime, est); //.. // Next, we create a series of transitions between these local-time descriptors // for the years 2007-2011. Note that the United States transitions to // daylight saving time on the second Sunday in March, at 2am local time (07:00 // UTC), and transitions back to standard time on the first Sunday in November // at 2am local time (06:00 UTC), resulting in an even number of transitions: //.. // static const bdlt::Datetime TRANSITION_TIMES[] = { // bdlt::Datetime(2007, 3, 11, 7), // bdlt::Datetime(2007, 11, 4, 6), // bdlt::Datetime(2008, 3, 9, 7), // bdlt::Datetime(2008, 11, 2, 6), // bdlt::Datetime(2009, 3, 8, 7), // bdlt::Datetime(2009, 11, 1, 6), // bdlt::Datetime(2010, 3, 14, 7), // bdlt::Datetime(2010, 11, 7, 6), // bdlt::Datetime(2011, 3, 13, 7), // bdlt::Datetime(2011, 11, 6, 6), // }; // const int NUM_TRANSITION_TIMES = // sizeof TRANSITION_TIMES / sizeof *TRANSITION_TIMES; // assert(0 == NUM_TRANSITION_TIMES % 2); // // for (int i = 0; i < NUM_TRANSITION_TIMES; i += 2) { // // const bsls::Epoch::TimeT64 edtTransitionTime = // bdlt::EpochUtil::convertToTimeT64(TRANSITION_TIMES[i]); // newYork.addTransition(edtTransitionTime, edt); // // const bsls::Epoch::TimeT64 estTransitionTime = // bdlt::EpochUtil::convertToTimeT64(TRANSITION_TIMES[i + 1]); // newYork.addTransition(estTransitionTime, est); // } //.. // Next, we verify that the time zone information we have created is considered // well-defined (as discussed above): //.. // assert(true == baltzo::ZoneinfoUtil::isWellFormed(newYork)); //.. // Finally, we create a 'baltzo::TestLoader' object, provide it the description // of 'newYork', and use it to initialize a 'baltzo::ZoneinfoCache' object: //.. // baltzo::TestLoader loader; // loader.setTimeZone(newYork); // baltzo::ZoneinfoCache cache(&loader); //.. // ///Example 1: Converting from a UTC Time to a Local Time ///- - - - - - - - - - - - - - - - - - - - - - - - - - - // In this example we demonstrate how to convert a UTC time to the // corresponding local time using the 'convertUtcToLocalTime' class method. // // We start by creating a 'bdlt::Datetime' representing the UTC time "Dec 12, // 2010 15:00": //.. // bdlt::Datetime utcTime(2010, 12, 12, 15, 0, 0); //.. // Now, we call 'convertUtcToLocalTime' and supply as input 'utcTime', the time // zone identifier for New York ("America/New_York"), and the cache of time // zone information created in the prologue: //.. // bdlt::DatetimeTz localNYTime; // baltzo::TimeZoneUtilImp::convertUtcToLocalTime(&localNYTime, // "America/New_York", // utcTime, // &cache); //.. // Finally we verify that 'localNYTime' is "Dec 12, 2010 10:00+5:00", the time // in New York corresponding to the UTC time "Dec 12, 2010 15:00". //.. // assert(utcTime == localNYTime.utcDatetime()); // assert(bdlt::Datetime(2010, 12, 12, 10) == localNYTime.localDatetime()); // assert(-5 * 60 == localNYTime.offset()); //.. #include <balscm_version.h> #include <baltzo_dstpolicy.h> #include <baltzo_localtimevalidity.h> #include <baltzo_zoneinfo.h> #include <bdlt_datetime.h> #include <bdlt_datetimetz.h> #include <bsl_iosfwd.h> namespace BloombergLP { namespace baltzo { class LocalTimePeriod; class ZoneinfoCache; // ===================== // class TimeZoneUtilImp // ===================== struct TimeZoneUtilImp { // This 'struct' provides a namespace for utility functions that convert // time values to, and from, local time. // CLASS METHODS static int convertUtcToLocalTime(bdlt::DatetimeTz *result, const char *resultTimeZoneId, const bdlt::Datetime& utcTime, ZoneinfoCache *cache); // Load, into the specified 'result', the local date-time value, in the // time zone indicated by the specified 'resultTimeZoneId', // corresponding to the specified 'utcTime', using time zone // information supplied by the specified 'cache'. Return 0 on success, // and a non-zero value otherwise. A return status of // 'ErrorCode::k_UNSUPPORTED_ID' indicates that 'resultTimeZoneId' is // not recognized, and a return status of 'ErrorCode::k_OUT_OF_RANGE' // indicates that an out of range value of 'result' would have // occurred. static void createLocalTimePeriod( LocalTimePeriod *result, const Zoneinfo::TransitionConstIterator& transition, const Zoneinfo& timeZone); // Load, into the specified 'result', attributes characterizing local // time indicated by the specified 'transition' in the specified // 'timeZone'. The behavior is undefined unless // 'ZoneinfoUtil::isWellFormed(timeZone)' is 'true' and 'transition' is // a valid, non-ending, iterator into the sequence of transitions // described by 'timeZone'. static int initLocalTime(bdlt::DatetimeTz *result, LocalTimeValidity::Enum *resultValidity, const bdlt::Datetime& localTime, const char *timeZoneId, DstPolicy::Enum dstPolicy, ZoneinfoCache *cache); // Load, into the specified 'result', the local date-time value -- // including the local date, time, and resolved UTC offset -- indicated // by the specified 'localTime' in the time zone indicated by the // specified 'timeZoneId', using the specified 'dstPolicy' to interpret // whether or not 'localTime' represents a daylight-saving time value, // and using time zone information supplied by the specified 'cache'. // Load, into the specified 'resultValidity' the value indicating the // whether 'localTime' is unique, ambiguous but valid, or invalid. // Return 0 on success, and a non-zero value otherwise. A return // status of 'ErrorCode::k_UNSUPPORTED_ID' indicates that 'timeZoneId' // is not recognized. static int loadLocalTimePeriodForUtc(LocalTimePeriod *result, const char *timeZoneId, const bdlt::Datetime& utcTime, ZoneinfoCache *cache); // Load, into the specified 'result', attributes characterizing local // time at the specified 'utcTime' in the time zone indicated by the // specified 'timeZoneId' (e.g., the offset from UTC, whether it is // daylight-saving time), as well as the time interval over which those // attributes apply, using time zone information supplied by the // specified 'cache'. Return 0 on success, and a non-zero value // otherwise. A return status of 'ErrorCode::k_UNSUPPORTED_ID' // indicates that 'timeZoneId' is not recognized. static void resolveLocalTime( bdlt::DatetimeTz *result, LocalTimeValidity::Enum *resultValidity, Zoneinfo::TransitionConstIterator *transitionIter, const bdlt::Datetime& localTime, DstPolicy::Enum dstPolicy, const Zoneinfo& timeZone); // Load, into the specified 'result', the local time and UTC offset of // the specified 'localTime' in the specified 'timeZone', using the // specified 'dstPolicy' to interpret whether or not 'localTime' // represents a daylight-saving time value; load into the specified // 'resultValidity' an indication of whether 'localTime' is valid and // unique, valid but ambiguous, or invalid; load into the specified // 'transitionIter' an iterator pointing to the transition that // characterizes the attributes of 'localTime'. The behavior is // undefined unless 'ZoneinfoUtil::isWellFormed(timeZone)' is 'true'. }; } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------