BDE 4.14.0 Production release
Loading...
Searching...
No Matches
baltzo_localtimeoffsetutil.h
Go to the documentation of this file.
1/// @file baltzo_localtimeoffsetutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// baltzo_localtimeoffsetutil.h -*-C++-*-
8#ifndef INCLUDED_BALTZO_LOCALTIMEOFFSETUTIL
9#define INCLUDED_BALTZO_LOCALTIMEOFFSETUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup baltzo_localtimeoffsetutil baltzo_localtimeoffsetutil
15/// @brief Provide utilities for a `bdlt_localtimeoffset` local time callback.
16/// @addtogroup bal
17/// @{
18/// @addtogroup baltzo
19/// @{
20/// @addtogroup baltzo_localtimeoffsetutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#baltzo_localtimeoffsetutil-purpose"> Purpose</a>
25/// * <a href="#baltzo_localtimeoffsetutil-classes"> Classes </a>
26/// * <a href="#baltzo_localtimeoffsetutil-description"> Description </a>
27/// * <a href="#baltzo_localtimeoffsetutil-usage"> Usage </a>
28/// * <a href="#baltzo_localtimeoffsetutil-example-1-using-localtimeoffset-as-the-local-time-offset-callback"> Example 1: Using localTimeOffset as the Local Time Offset Callback </a>
29///
30/// # Purpose {#baltzo_localtimeoffsetutil-purpose}
31/// Provide utilities for a @ref bdlt_localtimeoffset local time callback.
32///
33/// # Classes {#baltzo_localtimeoffsetutil-classes}
34///
35/// - baltzo::LocalTimeOffsetUtil: utilities managing a local time callback
36///
37/// @see bdlt_localtimeoffset
38///
39/// # Description {#baltzo_localtimeoffsetutil-description}
40/// This component, `baltzo::LocalTimeOffsetUtil`, provides
41/// `baltzo::LocalTimeOffsetUtil::localTimeOffset`, a high performance
42/// `bdlt::LocalTimeOffset` local time offset callback function, which accesses
43/// the Zoneinfo database. To achieve high performance, this function refers to
44/// a cached copy of local time period information (which includes the local
45/// time offset from UTC) that is populated by a call to one of the `configure`
46/// methods. The cache *must* be configured prior to the first call of
47/// `localTimeOffset`. That cached information is updated on receipt of a
48/// request with a datetime value outside of the range covered by the cached
49/// information. As there are usually are only a few timezone transitions per
50/// year, the cache hit rate should be very high for typical applications. The
51/// cached information might be invalidated by updates to the Zoneinfo database;
52/// however, those occur are also infrequent events.
53///
54/// A successful return from one of the `configure` methods is a prerequisite to
55/// the use of most of the other functions provided here. Most methods are
56/// thread-safe. Refer to the function-level documentation for details.
57///
58/// ## Usage {#baltzo_localtimeoffsetutil-usage}
59///
60///
61/// This section illustrates intended use of this component.
62///
63/// ### Example 1: Using localTimeOffset as the Local Time Offset Callback {#baltzo_localtimeoffsetutil-example-1-using-localtimeoffset-as-the-local-time-offset-callback}
64///
65///
66/// Suppose we must quickly generate time stamp values in local time (e.g., on
67/// records for a high frequency logger) and the default performance of the
68/// relevant methods of `bdlt::CurrentTime` is inadequate. Further suppose that
69/// we must do so arbitrary time values and time zones. Those requirements can
70/// be met by installing the `localTimeOffset` method of
71/// `baltzo::LocalTimeOffsetUtil` as the local time callback used by
72/// `bdlt::CurrentTime`.
73///
74/// First, specify the time zone to be used by the callback and a UTC date time
75/// for the initial offset information in the cache.
76/// @code
77/// assert(0 == baltzo::LocalTimeOffsetUtil::updateCount());
78///
79/// int status = baltzo::LocalTimeOffsetUtil::configure("America/New_York",
80/// bdlt::Datetime(2013,
81/// 2,
82/// 26));
83/// assert(0 == status);
84/// assert(1 == baltzo::LocalTimeOffsetUtil::updateCount());
85///
86/// bsl::string timezone;
87///
88/// baltzo::LocalTimeOffsetUtil::loadTimezone(&timezone);
89/// assert(0 == strcmp("America/New_York", timezone.c_str()));
90/// @endcode
91/// Notice that the value returned by the `updateCount` method is increased by
92/// one after then time zone information has been set.
93///
94/// Then, use the `setLoadLocalTimeOffsetCallback` method to set the
95/// `localTimeOffset` of `baltzo::LocalTimeOffsetUtil` as the local time offset
96/// callback used in `bdlt::CurrentTime`.
97/// @code
98/// bdlt::LocalTimeOffset::LocalTimeOffsetCallback previousCallback =
99/// baltzo::LocalTimeOffsetUtil::setLoadLocalTimeOffsetCallback();
100///
101/// assert(&baltzo::LocalTimeOffsetUtil::localTimeOffset
102/// == bdlt::CurrentTime::localTimeOffsetCallback());
103/// @endcode
104/// Notice that previously installed callback was saved so we can restore it, if
105/// needed.
106///
107/// Now, calls to `bdlt::CurrentTime` methods will use the method we installed.
108/// For example, we can check the time offset in New York for three dates of
109/// interest:
110/// @code
111/// bsls::Types::Int64 offsetInSeconds =
112/// bdlt::LocalTimeOffset::localTimeOffset(bdlt::Datetime(2013, 2, 26))
113/// .totalSeconds();
114/// assert( 0 == status);
115/// assert(-5 * 3600 == offsetInSeconds);
116/// assert( 1 == baltzo::LocalTimeOffsetUtil::updateCount());
117///
118/// baltzo::LocalTimeOffsetUtil::loadTimezone(&timezone);
119/// assert( 0 == strcmp("America/New_York", timezone.c_str()));
120///
121/// offsetInSeconds =
122/// bdlt::LocalTimeOffset::localTimeOffset(bdlt::Datetime(2013, 7, 4))
123/// .totalSeconds();
124/// assert(-4 * 3600 == offsetInSeconds);
125/// assert( 2 == baltzo::LocalTimeOffsetUtil::updateCount());
126/// baltzo::LocalTimeOffsetUtil::loadTimezone(&timezone);
127/// assert( 0 == strcmp("America/New_York", timezone.c_str()));
128///
129/// offsetInSeconds =
130/// bdlt::LocalTimeOffset::localTimeOffset(bdlt::Datetime(2013, 12, 21))
131/// .totalSeconds();
132/// assert(-5 * 3600 == offsetInSeconds);
133/// assert( 3 == baltzo::LocalTimeOffsetUtil::updateCount());
134/// baltzo::LocalTimeOffsetUtil::loadTimezone(&timezone);
135/// assert( 0 == strcmp("America/New_York", timezone.c_str()));
136/// @endcode
137/// Notice that the value returned by `updateCount()` is unchanged by our first
138/// request, but incremented by the second and third request, which transitions
139/// into and then out of daylight saving time. Also notice that the updates
140/// change the offset information but do not change the timezone.
141///
142/// Finally, we restore the original local time callback.
143/// @code
144/// previousCallback = bdlt::LocalTimeOffset::setLocalTimeOffsetCallback(
145/// previousCallback);
146/// ASSERT(previousCallback == &baltzo::LocalTimeOffsetUtil::localTimeOffset);
147/// @endcode
148/// @}
149/** @} */
150/** @} */
151
152/** @addtogroup bal
153 * @{
154 */
155/** @addtogroup baltzo
156 * @{
157 */
158/** @addtogroup baltzo_localtimeoffsetutil
159 * @{
160 */
161
162#include <baltzo_localtimeperiod.h>
163#include <baltzo_timezoneutil.h>
164
165#include <balscm_version.h>
166
167#include <bdlt_currenttime.h>
168#include <bdlt_datetime.h>
169#include <bdlt_localtimeoffset.h>
170
171#include <bslmt_rwmutex.h>
172
173#include <bsls_libraryfeatures.h>
174
175#include <bsl_string.h>
176
177#include <bsls_atomic.h>
178
179
180namespace baltzo {
181
182 // ==========================
183 // struct LocalTimeOffsetUtil
184 // ==========================
185
186/// This `struct` provides a namespace for a `bdlt::LocalTimeOffset` local
187/// time offset callback, and functions that manage the timezone information
188/// reported by that callback. All public methods are **thread-safe**.
190
191 // CLASS DATA
192 private:
193 static bsls::AtomicInt s_updateCount;
194
195 // PRIVATE CLASS METHODS
196
197 /// Set the local time period information used by the `localTimeOffset`
198 /// method according to the specified `timezone` at the specified
199 /// `utcDatetime`. Return 0 on success, and a non-zero value otherwise.
200 /// This method is *not* thread-safe.
201 static int configureImp(const char *timezone,
202 const bdlt::Datetime& utcDatetime);
203
204 /// Return the address of the current local time period information.
205 /// This method is *not* thread-safe.
206 static LocalTimePeriod *privateLocalTimePeriod();
207
208 /// Return the address of the lock controlling access to the local time
209 /// period information. This method is *not* thread-safe.
210 static bslmt::RWMutex *privateLock();
211
212 /// Return the address of the time period information. This method is
213 /// *not* thread-safe.
214 static bsl::string *privateTimezone();
215
216 // CLASS METHODS
217 public:
218
219 // *** local time offset methods ***
220
221#ifndef BDE_OMIT_INTERNAL_DEPRECATED // pending deprecation
222
223 // DEPRECATED CLASS METHODS
224
225 /// @deprecated Use @ref localTimeOffset instead.
226 ///
227 /// Efficiently load to the specified `result` the offset of the local
228 /// time from UTC for the specified `utcDatetime`. This function is
229 /// thread-safe. The behavior is undefined unless the local time zone
230 /// has been previously established by a call to the `configure` method.
231 /// This method *is* thread-safe. Note that this function is no longer
232 /// used as a callback function. It exisis for backwards compatibility
233 /// with code that called it directly, and is deprecated.
234 static void loadLocalTimeOffset(int *result,
235 const bdlt::Datetime& utcDatetime);
236
237#endif // BDE_OMIT_INTERNAL_DEPRECATED -- pending deprecation
238
239 /// Return the offset of the local time from UTC for the specified
240 /// `utcDatetime`. This function is thread-safe. The behavior is
241 /// undefined unless the local time zone has been previously established
242 /// by a call to the `configure` method. This method *is* thread-safe.
244 const bdlt::Datetime& utcDatetime);
245
246 /// Set `localTimeOffset` as the local time offset callback of
247 /// `bdlt::CurrentTime`. Return the previously installed callback.
248 /// This method is *not* thread-safe.
251
252 // *** configure methods ***
253
254 /// Set the local time period information used by the `localTimeOffset`
255 /// method to that for the time zone in the `TZ` environment variable at
256 /// the current UTC datetime. Return 0 on success, and a non-zero value
257 /// otherwise. This method is *not* thread-safe. The behavior is
258 /// undefined if the environment changes (e.g., a call to the `putenv`
259 /// POSIX function) during the invocation of this method.
260 static int configure();
261
262 /// Set the local time period information used by the `localTimeOffset`
263 /// method to that for specified `timezone` at the current UTC datetime.
264 /// Return 0 on success, and a non-zero value otherwise. This method is
265 /// *not* thread-safe.
266 static int configure(const char *timezone);
267
268 /// Set the local time period information used by the `localTimeOffset`
269 /// method to that for the specified `timezone` at the specified
270 /// `utcDatetime`. Return 0 on success, and a non-zero value otherwise.
271 /// This method is *not* thread-safe.
272 static int configure(const char *timezone,
273 const bdlt::Datetime& utcDatetime);
274
275 // *** accessor methods ***
276
277 /// Load to the specified `localTimePeriod` the local time period
278 /// information currently used by the `localTimeOffset` method. That
279 /// information is updated when `localTimeOffset` is called with a
280 /// `utcDatetime` outside the range `localTimePeriod().utcStartTime()`
281 /// (inclusive) `localTimePeriod().utcEndTime()` (exclusive). This
282 /// method is *not* thread-safe. The behavior is undefined if this
283 /// method is invoked before the successful invocation of a `configure`
284 /// method.
285 static void loadLocalTimePeriod(LocalTimePeriod *localTimePeriod);
286
287 static void loadTimezone(bsl::string *timezone);
288 /// Load to the specified `timezone` time zone identifier used to
289 /// determine the local time offset from UTC. This method *is* not
290 /// thread-safe. The behavior is undefined if this method is invoked
291 /// before the successful invocation of a `configure` method.
292 static void loadTimezone(std::string *timezone);
293#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
294 static void loadTimezone(std::pmr::string *timezone);
295#endif
296
297 /// Return the number of successful updates of the local time period
298 /// information since the start of the process. This count is
299 /// incremented on calls to any of the `setTimeZone` methods and when
300 /// `loadLocalTimePeriod` is called with a `utcDatetime` outside the
301 /// range of the current local time period information. This method
302 /// *is* thread-safe.
303 static int updateCount();
304};
305
306// ============================================================================
307// INLINE DEFINITIONS
308// ============================================================================
309
310 // --------------------------
311 // struct LocalTimeOffsetUtil
312 // --------------------------
313
314// CLASS METHODS
315
316 // *** local time offset methods ***
317
318inline
325
326 // *** accessor methods ***
327
328inline
330{
331 return s_updateCount;
332}
333
334} // close package namespace
335
336
337#endif
338
339// ----------------------------------------------------------------------------
340// Copyright 2018 Bloomberg Finance L.P.
341//
342// Licensed under the Apache License, Version 2.0 (the "License");
343// you may not use this file except in compliance with the License.
344// You may obtain a copy of the License at
345//
346// http://www.apache.org/licenses/LICENSE-2.0
347//
348// Unless required by applicable law or agreed to in writing, software
349// distributed under the License is distributed on an "AS IS" BASIS,
350// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
351// See the License for the specific language governing permissions and
352// limitations under the License.
353// ----------------------------- END-OF-FILE ----------------------------------
354
355/** @} */
356/** @} */
357/** @} */
Definition baltzo_localtimeperiod.h:211
Definition bdlt_datetime.h:331
Definition bslstl_string.h:1281
Definition bslmt_rwmutex.h:147
Definition bsls_atomic.h:743
Definition bsls_timeinterval.h:301
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition baltzo_datafileloader.h:263
Definition baltzo_localtimeoffsetutil.h:189
static int configure(const char *timezone, const bdlt::Datetime &utcDatetime)
static int configure(const char *timezone)
static bsls::TimeInterval localTimeOffset(const bdlt::Datetime &utcDatetime)
static void loadTimezone(bsl::string *timezone)
static bdlt::LocalTimeOffset::LocalTimeOffsetCallback setLoadLocalTimeOffsetCallback()
Definition baltzo_localtimeoffsetutil.h:320
static void loadLocalTimePeriod(LocalTimePeriod *localTimePeriod)
static void loadLocalTimeOffset(int *result, const bdlt::Datetime &utcDatetime)
static int updateCount()
Definition baltzo_localtimeoffsetutil.h:329
static void loadTimezone(std::string *timezone)
static LocalTimeOffsetCallback setLocalTimeOffsetCallback(LocalTimeOffsetCallback callback)
Definition bdlt_localtimeoffset.h:322
bsls::TimeInterval(* LocalTimeOffsetCallback)(const Datetime &utcDatetime)
Definition bdlt_localtimeoffset.h:261