BDE 4.39.x 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**.
189///
190/// See @ref baltzo_localtimeoffsetutil
192
193 // CLASS DATA
194 private:
195 static bsls::AtomicInt s_updateCount;
196
197 // PRIVATE CLASS METHODS
198
199 /// Set the local time period information used by the `localTimeOffset`
200 /// method according to the specified `timezone` at the specified
201 /// `utcDatetime`. Return 0 on success, and a non-zero value otherwise.
202 /// This method is *not* thread-safe.
203 static int configureImp(const char *timezone,
204 const bdlt::Datetime& utcDatetime);
205
206 /// Return the address of the current local time period information.
207 /// This method is *not* thread-safe.
208 static LocalTimePeriod *privateLocalTimePeriod();
209
210 /// Return the address of the lock controlling access to the local time
211 /// period information. This method is *not* thread-safe.
212 static bslmt::RWMutex *privateLock();
213
214 /// Return the address of the time period information. This method is
215 /// *not* thread-safe.
216 static bsl::string *privateTimezone();
217
218 // CLASS METHODS
219 public:
220
221 // *** local time offset methods ***
222
223#ifndef BDE_OMIT_INTERNAL_DEPRECATED // pending deprecation
224
225 // DEPRECATED CLASS METHODS
226
227 /// Efficiently load to the specified `result` the offset of the local
228 /// time from UTC for the specified `utcDatetime`. This function is thread-safe.
229 ///
230 /// \pre The behavior is undefined unless the local time zone
231 /// has been previously established by a call to the `configure` method. This method *is* thread-safe.
232 ///
233 /// \note Note that this function is no longer
234 /// used as a callback function. It exisis for backwards compatibility
235 /// with code that called it directly, and is deprecated.
236 ///
237 /// @deprecated Use @ref localTimeOffset instead.
238 static void loadLocalTimeOffset(int *result,
239 const bdlt::Datetime& utcDatetime);
240
241#endif // BDE_OMIT_INTERNAL_DEPRECATED -- pending deprecation
242
243 /// Return the offset of the local time from UTC for the specified
244 /// `utcDatetime`. This function is thread-safe.
245 ///
246 /// \pre The behavior is undefined unless the local time zone has been previously established
247 /// by a call to the `configure` method. This method *is* thread-safe.
249 const bdlt::Datetime& utcDatetime);
250
251 /// Set `localTimeOffset` as the local time offset callback of
252 /// `bdlt::CurrentTime`. Return the previously installed callback.
253 /// This method is *not* thread-safe.
256
257 // *** configure methods ***
258
259 /// Set the local time period information used by the `localTimeOffset`
260 /// method to that for the time zone in the `TZ` environment variable at
261 /// the current UTC datetime. Return 0 on success, and a non-zero value
262 /// otherwise. This method is *not* thread-safe.
263 ///
264 /// \pre The behavior is undefined if the environment changes (e.g., a call to the `putenv`
265 /// POSIX function) during the invocation of this method.
266 static int configure();
267
268 /// Set the local time period information used by the `localTimeOffset`
269 /// method to that for specified `timezone` at the current UTC datetime.
270 /// Return 0 on success, and a non-zero value otherwise. This method is
271 /// *not* thread-safe.
272 static int configure(const char *timezone);
273
274 /// Set the local time period information used by the `localTimeOffset`
275 /// method to that for the specified `timezone` at the specified
276 /// `utcDatetime`. Return 0 on success, and a non-zero value otherwise.
277 /// This method is *not* thread-safe.
278 static int configure(const char *timezone,
279 const bdlt::Datetime& utcDatetime);
280
281 // *** accessor methods ***
282
283 /// Load to the specified `localTimePeriod` the local time period
284 /// information currently used by the `localTimeOffset` method. That
285 /// information is updated when `localTimeOffset` is called with a
286 /// `utcDatetime` outside the range `localTimePeriod().utcStartTime()`
287 /// (inclusive) `localTimePeriod().utcEndTime()` (exclusive). This method is *not* thread-safe.
288 ///
289 /// \pre The behavior is undefined if this
290 /// method is invoked before the successful invocation of a `configure`
291 /// method.
292 static void loadLocalTimePeriod(LocalTimePeriod *localTimePeriod);
293
294 /// Load to the specified `timezone` time zone identifier used to
295 /// determine the local time offset from UTC. This method *is* not thread-safe.
296 ///
297 /// \pre The behavior is undefined if this method is invoked
298 /// before the successful invocation of a `configure` method.
299 static void loadTimezone(bsl::string *timezone);
300 static void loadTimezone(std::string *timezone);
301#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
302 static void loadTimezone(std::pmr::string *timezone);
303#endif
304
305 /// Return the number of successful updates of the local time period
306 /// information since the start of the process. This count is
307 /// incremented on calls to any of the `setTimeZone` methods and when
308 /// `loadLocalTimePeriod` is called with a `utcDatetime` outside the
309 /// range of the current local time period information. This method
310 /// *is* thread-safe.
311 static int updateCount();
312};
313
314// ============================================================================
315// INLINE DEFINITIONS
316// ============================================================================
317
318 // --------------------------
319 // struct LocalTimeOffsetUtil
320 // --------------------------
321
322// CLASS METHODS
323
324 // *** local time offset methods ***
325
326inline
333
334 // *** accessor methods ***
335
336inline
338{
339 return s_updateCount;
340}
341
342} // close package namespace
343
344
345#endif
346
347// ----------------------------------------------------------------------------
348// Copyright 2018 Bloomberg Finance L.P.
349//
350// Licensed under the Apache License, Version 2.0 (the "License");
351// you may not use this file except in compliance with the License.
352// You may obtain a copy of the License at
353//
354// http://www.apache.org/licenses/LICENSE-2.0
355//
356// Unless required by applicable law or agreed to in writing, software
357// distributed under the License is distributed on an "AS IS" BASIS,
358// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
359// See the License for the specific language governing permissions and
360// limitations under the License.
361// ----------------------------- END-OF-FILE ----------------------------------
362
363/** @} */
364/** @} */
365/** @} */
Definition baltzo_localtimeperiod.h:208
Definition bdlt_datetime.h:330
Definition bslstl_string.h:1252
Definition bslmt_rwmutex.h:148
Definition bsls_atomic.h:744
Definition bsls_timeinterval.h:307
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition baltzo_datafileloader.h:259
Definition baltzo_localtimeoffsetutil.h:191
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:328
static void loadLocalTimePeriod(LocalTimePeriod *localTimePeriod)
static void loadLocalTimeOffset(int *result, const bdlt::Datetime &utcDatetime)
static int updateCount()
Definition baltzo_localtimeoffsetutil.h:337
static void loadTimezone(std::string *timezone)
static LocalTimeOffsetCallback setLocalTimeOffsetCallback(LocalTimeOffsetCallback callback)
Definition bdlt_localtimeoffset.h:327
bsls::TimeInterval(* LocalTimeOffsetCallback)(const Datetime &utcDatetime)
Definition bdlt_localtimeoffset.h:264