BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt_localtimeoffset.h
Go to the documentation of this file.
1/// @file bdlt_localtimeoffset.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlt_localtimeoffset.h -*-C++-*-
8#ifndef INCLUDED_BDLT_LOCALTIMEOFFSET
9#define INCLUDED_BDLT_LOCALTIMEOFFSET
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlt_localtimeoffset bdlt_localtimeoffset
15/// @brief Provide utilities to retrieve the local time offset.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlt
19/// @{
20/// @addtogroup bdlt_localtimeoffset
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlt_localtimeoffset-purpose"> Purpose</a>
25/// * <a href="#bdlt_localtimeoffset-classes"> Classes </a>
26/// * <a href="#bdlt_localtimeoffset-description"> Description </a>
27/// * <a href="#bdlt_localtimeoffset-thread-safety"> Thread Safety </a>
28/// * <a href="#bdlt_localtimeoffset-usage"> Usage </a>
29/// * <a href="#bdlt_localtimeoffset-example-1-basic-bdlt-localtimeoffset-usage"> Example 1: Basic bdlt::LocalTimeOffset Usage </a>
30/// * <a href="#bdlt_localtimeoffset-example-2-using-the-local-time-offset-callback"> Example 2: Using the Local Time Offset Callback </a>
31///
32/// # Purpose {#bdlt_localtimeoffset-purpose}
33/// Provide utilities to retrieve the local time offset.
34///
35/// # Classes {#bdlt_localtimeoffset-classes}
36///
37/// - bdlt::LocalTimeOffset: namespace for local time offset functions
38///
39/// @see bsls_timeinterval, bsls_systemtime, bdlt_currenttime
40///
41/// # Description {#bdlt_localtimeoffset-description}
42/// This component provides a `struct`, `bdlt::LocalTimeOffset`, in
43/// which are defined a series of static methods for using a callback function
44/// to retrieve the local time offset (the difference between the currently
45/// executing task's local time and UTC time) at a specified UTC date and time.
46/// `LocalTimeoffset` provides a function `localTimeOffset` that delegates to
47/// the currently installed local time offset callback. By default,
48/// `localTimeOffsetDefault` is installed as the local time offset callback.
49/// Clients can configure the default callback function by calling the
50/// `setLocalTimeOffsetCallback` function.
51///
52/// ## Thread Safety {#bdlt_localtimeoffset-thread-safety}
53///
54///
55/// The functions provided by `bdlt::LocalTimeOffset` are *thread-safe* (meaning
56/// they may be called concurrently from multiple threads), including those that
57/// set and retrieve the callback function. In addition, user-supplied callback
58/// functions must be *thread-safe*.
59///
60/// ## Usage {#bdlt_localtimeoffset-usage}
61///
62///
63/// This section illustrates intended use of this component.
64///
65/// ### Example 1: Basic bdlt::LocalTimeOffset Usage {#bdlt_localtimeoffset-example-1-basic-bdlt-localtimeoffset-usage}
66///
67///
68/// This example demonstrates how to use `bdlt::LocalTimeOffset`.
69///
70/// First, obtain the current UTC time - ignoring milliseconds - using
71/// `bsls::SystemTime` and `bdlt::EpochUtil` (note that clients may prefer
72/// @ref bdlt_currenttime , which is not shown here for dependency reasons):
73/// @code
74/// bsls::TimeInterval now = bsls::SystemTime::nowRealtimeClock();
75///
76/// bdlt::Datetime utc = bdlt::EpochUtil::epoch() +
77/// bdlt::DatetimeInterval(0, 0, 0, now.seconds());
78/// @endcode
79/// Then, obtain the local time offset:
80/// @code
81/// bsls::TimeInterval localOffset =
82/// bdlt::LocalTimeOffset::localTimeOffset(utc);
83/// @endcode
84/// Next, add the offset to the UTC time to obtain the local time:
85/// @code
86/// bdlt::Datetime local = utc;
87/// local.addSeconds(localOffset.seconds());
88/// @endcode
89/// Finally, stream the two time values to `stdout`:
90/// @code
91/// bsl::cout << "utc = " << utc << bsl::endl;
92/// bsl::cout << "local = " << local << bsl::endl;
93/// @endcode
94/// The streaming operator produces output in the following format on `stdout`:
95/// @code
96/// utc = ddMONyyyy_hh:mm::ss.000
97/// local = ddMONyyyy_hh:mm::ss.000
98/// @endcode
99///
100/// ### Example 2: Using the Local Time Offset Callback {#bdlt_localtimeoffset-example-2-using-the-local-time-offset-callback}
101///
102///
103/// Suppose one has to provide time stamp values that always reflect local time
104/// for a given location, even when local time transitions into and out of
105/// daylight saving time. Further suppose that one must do this quite often
106/// (e.g., for every record in a high frequency log), so the performance of the
107/// default method for calculating local time offset is not adequate. Creation
108/// and installation of a specialized user-defined callback for local time
109/// offset allows one to solve this problem.
110///
111/// First, create a utility class that provides a method of type
112/// `bdlt::LocalTimeOffset::LocalTimeOffsetCallback` that is valid for the
113/// location of interest (New York) for the period of interest (the year 2013).
114/// @code
115/// struct MyLocalTimeOffsetUtilNewYork2013 {
116///
117/// private:
118/// // DATA
119/// static int s_useCount;
120/// static bdlt::Datetime s_startOfDaylightSavingTime; // UTC Datetime
121/// static bdlt::Datetime s_resumptionOfStandardTime; // UTC Datetime
122///
123/// public:
124/// // CLASS METHODS
125///
126/// /// Return a `bsls::TimeInterval` value representing the difference
127/// /// between the local time for the "America/New_York" timezone and
128/// /// UTC time at the specified `utcDatetime`. The behavior is
129/// /// undefined unless `2013 == utcDatetime.date().year()`.
130/// static bsls::TimeInterval localTimeOffset(
131/// const bdlt::Datetime& utcDatetime);
132///
133/// /// Return the number of invocations of the `localTimeOffset` since
134/// /// the start of the process.
135/// static int useCount();
136/// };
137///
138/// // DATA
139/// int MyLocalTimeOffsetUtilNewYork2013::s_useCount = 0;
140///
141/// bdlt::Datetime
142/// MyLocalTimeOffsetUtilNewYork2013::s_startOfDaylightSavingTime(2013,
143/// 3,
144/// 10,
145/// 7);
146/// bdlt::Datetime
147/// MyLocalTimeOffsetUtilNewYork2013::s_resumptionOfStandardTime(2013,
148/// 11,
149/// 3,
150/// 6);
151///
152/// // CLASS METHODS
153/// bsls::TimeInterval MyLocalTimeOffsetUtilNewYork2013::localTimeOffset(
154/// const bdlt::Datetime& utcDatetime)
155/// {
156/// assert(2013 == utcDatetime.date().year());
157///
158/// ++s_useCount;
159/// int seconds = utcDatetime < s_startOfDaylightSavingTime ? -18000 :
160/// utcDatetime < s_resumptionOfStandardTime ? -14400 :
161/// -18000;
162/// return bsls::TimeInterval(seconds, 0);
163/// }
164///
165/// int MyLocalTimeOffsetUtilNewYork2013::useCount()
166/// {
167/// return s_useCount;
168/// }
169/// @endcode
170/// Note that the transition times into and out of daylight saving for New York
171/// are given in UTC. Also notice that we do not attempt to make the
172/// `localTimeOffset` method `inline`, since we must take its address to install
173/// it as the callback.
174///
175/// Then, we install this `localTimeOffset` as the local time offset callback.
176/// @code
177/// bdlt::LocalTimeOffset::LocalTimeOffsetCallback defaultCallback =
178/// bdlt::LocalTimeOffset::setLocalTimeOffsetCallback(
179/// &MyLocalTimeOffsetUtilNewYork2013::
180/// localTimeOffset);
181///
182/// assert(bdlt::LocalTimeOffset::localTimeOffsetDefault == defaultCallback);
183/// assert(&MyLocalTimeOffsetUtilNewYork2013::localTimeOffset
184/// == bdlt::LocalTimeOffset::localTimeOffsetCallback());
185/// @endcode
186/// Now, we can use the `bdlt::LocalTimeOffset::localTimeOffset` method to
187/// obtain the local time offsets in New York on several dates of interest. The
188/// increasing values from our `useCount` method assures us that the callback we
189/// defined is indeed being used.
190/// @code
191/// assert(0 == MyLocalTimeOffsetUtilNewYork2013::useCount());
192///
193/// bsls::Types::Int64 offset;
194/// bdlt::Datetime newYearsDay(2013, 1, 1);
195/// bdlt::Datetime independenceDay(2013, 7, 4);
196/// bdlt::Datetime newYearsEve(2013, 12, 31);
197///
198/// offset = bdlt::LocalTimeOffset::localTimeOffset(newYearsDay).seconds();
199/// assert(-5 * 3600 == offset);
200/// assert( 1 == MyLocalTimeOffsetUtilNewYork2013::useCount());
201///
202/// offset = bdlt::LocalTimeOffset::localTimeOffset(independenceDay).seconds();
203/// assert(-4 * 3600 == offset);
204/// assert( 2 == MyLocalTimeOffsetUtilNewYork2013::useCount());
205///
206/// offset = bdlt::LocalTimeOffset::localTimeOffset(newYearsEve).seconds();
207/// assert(-5 * 3600 == offset);
208/// assert( 3 == MyLocalTimeOffsetUtilNewYork2013::useCount());
209/// @endcode
210/// Finally, to be neat, we restore the local time offset callback to the
211/// default callback:
212/// @code
213/// bdlt::LocalTimeOffset::setLocalTimeOffsetCallback(defaultCallback);
214/// assert(&bdlt::LocalTimeOffset::localTimeOffsetDefault
215/// == bdlt::LocalTimeOffset::localTimeOffsetCallback());
216/// @endcode
217/// @}
218/** @} */
219/** @} */
220
221/** @addtogroup bdl
222 * @{
223 */
224/** @addtogroup bdlt
225 * @{
226 */
227/** @addtogroup bdlt_localtimeoffset
228 * @{
229 */
230
231#include <bdlscm_version.h>
232
233#include <bdlt_datetime.h>
234
235#include <bsls_assert.h>
237#include <bsls_review.h>
238#include <bsls_timeinterval.h>
239#include <bsls_types.h>
240
241
242namespace bdlt {
243
244 // =====================
245 // class LocalTimeOffset
246 // =====================
247
248/// This `struct` provides a namespace for local-time-offset procedures
249/// including a configurable global callback mechanism. The use of these
250/// procedures is thread-safe (see `Thread Safety`).
252
253 // TYPES
254
255 /// `LocalTimeOffsetCallback` is an alias for the type of a function
256 /// that returns a `bsls::TimeInterval` value representing the
257 /// difference between local time and UTC time at the specified
258 /// `utcDatetime`. This function must be thread-safe in multi-threaded
259 /// builds. Note that the installed callback function must have
260 /// geographic information specifying the local timezone.
262 const Datetime& utcDatetime);
263
264 private:
265 static bsls::AtomicOperations::AtomicTypes::Pointer
266 s_localTimeOffsetCallback_p;
267 // address of local-time-offset callback
268
269 public:
270 // CLASS METHODS
271
272 // ** computation method **
273
274 /// Return a `bsls::TimeInterval` value representing the difference
275 /// between local time and UTC time at the specified `utcDatetime`.
276 /// This method uses the currently installed local-time-offset callback
277 /// mechanism.
278 static bsls::TimeInterval localTimeOffset(const Datetime& utcDatetime);
279
280 // ** default callback **
281
282 /// Return a `bsls::TimeInterval` value representing the difference
283 /// between local time and UTC time at the specified `utcDatetime`.
284 /// Note that the local time zone is determined by the `TZ` environment
285 /// variable in the same manner as the `localtime` POSIX function.
287 const Datetime& utcDatetime);
288
289 // ** set callback **
290
291 /// Set the specified `callback` as the function to be used to return a
292 /// `bsls::TimeInterval` value representing the difference between
293 /// local time and UTC time at a specified UTC date and time. Return
294 /// the previously installed `LocalTimeOffsetCallback` function. The
295 /// behavior is undefined unless `0 != callback`.
297 LocalTimeOffsetCallback callback);
298
299 // ** get current callback **
300
301 /// Return the currently installed `LocalTimeOffsetCallback` function.
303};
304
305// ============================================================================
306// INLINE DEFINITIONS
307// ============================================================================
308
309 // ** computation method **
310
311inline
313 localTimeOffset(const Datetime& utcDatetime)
314{
315 return localTimeOffsetCallback()(utcDatetime);
316}
317
318 // ** set callback **
319
320inline
322 LocalTimeOffset::setLocalTimeOffsetCallback(LocalTimeOffsetCallback callback)
323{
324 BSLS_ASSERT(callback);
325
328 &s_localTimeOffsetCallback_p,
329 reinterpret_cast<void *>(
330 reinterpret_cast<bsls::Types::IntPtr>(callback)));
331
332 return previousCallback;
333}
334
335 // ** get current callback **
336
337inline
340{
341 return reinterpret_cast<LocalTimeOffsetCallback>(
342 reinterpret_cast<bsls::Types::IntPtr>(
344 &s_localTimeOffsetCallback_p)));
345}
346
347} // close package namespace
348
349
350#endif
351
352// ----------------------------------------------------------------------------
353// Copyright 2014 Bloomberg Finance L.P.
354//
355// Licensed under the Apache License, Version 2.0 (the "License");
356// you may not use this file except in compliance with the License.
357// You may obtain a copy of the License at
358//
359// http://www.apache.org/licenses/LICENSE-2.0
360//
361// Unless required by applicable law or agreed to in writing, software
362// distributed under the License is distributed on an "AS IS" BASIS,
363// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
364// See the License for the specific language governing permissions and
365// limitations under the License.
366// ----------------------------- END-OF-FILE ----------------------------------
367
368/** @} */
369/** @} */
370/** @} */
Definition bdlt_datetime.h:331
Definition bsls_timeinterval.h:301
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bbldc_basicisma30360.h:112
Definition bdlt_localtimeoffset.h:251
static bsls::TimeInterval localTimeOffsetDefault(const Datetime &utcDatetime)
static LocalTimeOffsetCallback localTimeOffsetCallback()
Return the currently installed LocalTimeOffsetCallback function.
Definition bdlt_localtimeoffset.h:339
static bsls::TimeInterval localTimeOffset(const Datetime &utcDatetime)
Definition bdlt_localtimeoffset.h:313
static LocalTimeOffsetCallback setLocalTimeOffsetCallback(LocalTimeOffsetCallback callback)
Definition bdlt_localtimeoffset.h:322
bsls::TimeInterval(* LocalTimeOffsetCallback)(const Datetime &utcDatetime)
Definition bdlt_localtimeoffset.h:261
static void * getPtrAcquire(AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations.h:2312
static void setPtrRelease(AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations.h:2345
std::ptrdiff_t IntPtr
Definition bsls_types.h:130