BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt_datetimeutil.h
Go to the documentation of this file.
1/// @file bdlt_datetimeutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlt_datetimeutil.h -*-C++-*-
8#ifndef INCLUDED_BDLT_DATETIMEUTIL
9#define INCLUDED_BDLT_DATETIMEUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlt_datetimeutil bdlt_datetimeutil
15/// @brief Provide common non-primitive operations on `bdlt::Datetime`.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlt
19/// @{
20/// @addtogroup bdlt_datetimeutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlt_datetimeutil-purpose"> Purpose</a>
25/// * <a href="#bdlt_datetimeutil-classes"> Classes </a>
26/// * <a href="#bdlt_datetimeutil-description"> Description </a>
27/// * <a href="#bdlt_datetimeutil-usage"> Usage </a>
28/// * <a href="#bdlt_datetimeutil-example-1-converting-between-bsl-tm-and-bdlt-datetime"> Example 1: Converting Between bsl::tm and bdlt::Datetime </a>
29///
30/// # Purpose {#bdlt_datetimeutil-purpose}
31/// Provide common non-primitive operations on `bdlt::Datetime`.
32///
33/// # Classes {#bdlt_datetimeutil-classes}
34///
35/// - bdlt::DatetimeUtil: non-primitive functions on `bdlt::Datetime`
36///
37/// @see bdlt_datetime, bdlt_datetimeinterval, bdlt_epochutil
38///
39/// # Description {#bdlt_datetimeutil-description}
40/// This component provides non-primitive operations on
41/// `bdlt::Datetime` objects. In particular, `bdlt::DatetimeUtil` supplies
42/// conversions of universal time to and from the C-standard `struct` `tm`
43/// (which we alias as `bsl::tm`) representations.
44///
45/// This utility component provides the following (static) methods:
46/// @code
47/// int convertFromTm(bdlt::Datetime *result, const tm& timeStruct);
48/// bsl::tm convertToTm(const bdlt::Datetime& datetime);
49/// @endcode
50///
51/// ## Usage {#bdlt_datetimeutil-usage}
52///
53///
54/// This section illustrates intended use of this component.
55///
56/// ### Example 1: Converting Between bsl::tm and bdlt::Datetime {#bdlt_datetimeutil-example-1-converting-between-bsl-tm-and-bdlt-datetime}
57///
58///
59/// When interfacing with legacy systems, we may encounter calls that represent
60/// date/time information using the standard `bsl::tm`. In such cases, we have
61/// to be able to convert that information to/from a `bdlt::Datetime` object in
62/// order to interface with the rest of our systems.
63///
64/// Suppose we have a legacy system that tracks last-access times in terms of
65/// `bsl::tm`. We can use the `convertToTm` and `convertFromTm` routines from
66/// this component to convert that information.
67///
68/// First, we define a class, `MyAccessTracker`, that the legacy system uses to
69/// manage last-access times (eliding the implementation for brevity):
70/// @code
71/// /// This class provides a facility for tracking last access times
72/// /// associated with usernames.
73/// class MyAccessTracker {
74///
75/// // LOCAL TYPE
76/// typedef bsl::map<bsl::string, bsl::tm> TStringTmMap;
77///
78/// // DATA
79/// TStringTmMap m_accesses; // map names to
80/// // accesses
81///
82/// public:
83/// // TRAITS
84/// BSLMF_NESTED_TRAIT_DECLARATION(MyAccessTracker,
85/// bslma::UsesBslmaAllocator);
86///
87/// // CREATORS
88///
89/// /// Create an object which will track the last access time ...
90/// explicit MyAccessTracker(bslma::Allocator *basicAllocator = 0);
91///
92/// // MANIPULATORS
93///
94/// /// Update the last access time for the specified `username` with
95/// /// the specified `accessTime`.
96/// void updateLastAccess(const bsl::string& username,
97/// const bsl::tm& accessTime);
98///
99/// // ACCESSORS
100///
101/// /// Load into the specified `result` the last access time associated
102/// /// with the specified `username`, if any. Return 0 on success, and
103/// /// non-0 (with no effect on `result`) if there's no access time
104/// /// associated with `username`.
105/// int getLastAccess(bsl::tm *result, const bsl::string& username) const;
106/// };
107/// @endcode
108/// Next, we define a utility to allow us to use `bdlt::Datetime` with our
109/// legacy access tracker:
110/// @code
111/// class MyAccessTrackerUtil {
112/// public:
113///
114/// /// Load into the specified `result` the last access time associated
115/// /// with the specified `username` in the specified `tracker`, if
116/// /// any. Returns 0 on success, and non-0 (with no effect on
117/// /// `result`) if there's no access time associated with `username`
118/// /// or the associated access time cannot be converted to
119/// /// `bdlt::Datetime`.
120/// static int getLastAccess(bdlt::Datetime *result,
121/// const MyAccessTracker& tracker,
122/// const bsl::string& username);
123///
124/// /// Update the instance pointed to by the specified `tracker` by
125/// /// adding the specified `username` with its associated specified
126/// /// `accessTime`.
127/// static void updateLastAccess(MyAccessTracker *tracker,
128/// const bsl::string& username,
129/// const bdlt::Datetime& accessTime);
130/// };
131/// @endcode
132/// Then, we implement `getLastAccess`:
133/// @code
134/// // -------------------------
135/// // class MyAccessTrackerUtil
136/// // -------------------------
137///
138/// int MyAccessTrackerUtil::getLastAccess(bdlt::Datetime *result,
139/// const MyAccessTracker& tracker,
140/// const bsl::string& username)
141/// {
142/// BSLS_ASSERT(result);
143///
144/// bsl::tm legacyAccessTime;
145///
146/// int rc = tracker.getLastAccess(&legacyAccessTime, username);
147///
148/// if (rc) {
149/// return rc; // RETURN
150/// }
151///
152/// return bdlt::DatetimeUtil::convertFromTm(result, legacyAccessTime);
153/// }
154/// @endcode
155/// Next, we implement `updateLastAccess`:
156/// @code
157/// void MyAccessTrackerUtil::updateLastAccess(
158/// MyAccessTracker *tracker,
159/// const bsl::string& username,
160/// const bdlt::Datetime& accessTime)
161/// {
162/// BSLS_ASSERT(tracker);
163///
164/// bsl::tm legacyAccessTime;
165///
166/// legacyAccessTime = bdlt::DatetimeUtil::convertToTm(accessTime);
167///
168/// tracker->updateLastAccess(username, legacyAccessTime);
169/// }
170/// @endcode
171/// Finally, we create an access tracker then interact with it using
172/// `bdlt::Datetime` times.
173/// @code
174/// /// Exercise `MyAccessTracker` for pedagogical purposes.
175/// void exerciseTracker()
176/// {
177/// MyAccessTracker accessTracker; // Datetime each user last accessed a
178/// // resource.
179///
180/// bsl::string richtofenName = "Baron von Richtofen";
181/// bdlt::Datetime richtofenDate(1918, 4, 21, 11, 0, 0);
182/// MyAccessTrackerUtil::updateLastAccess(&accessTracker,
183/// richtofenName,
184/// richtofenDate);
185///
186/// // ... some time later ....
187///
188/// bdlt::Datetime lastAccessTime;
189/// int rc = MyAccessTrackerUtil::getLastAccess(&lastAccessTime,
190/// accessTracker,
191/// richtofenName);
192/// assert(0 == rc);
193/// assert(lastAccessTime == richtofenDate);
194///
195/// // Do something with the retrieved date...
196/// }
197/// @endcode
198/// @}
199/** @} */
200/** @} */
201
202/** @addtogroup bdl
203 * @{
204 */
205/** @addtogroup bdlt
206 * @{
207 */
208/** @addtogroup bdlt_datetimeutil
209 * @{
210 */
211
212#include <bdlscm_version.h>
213
214#include <bdlt_datetime.h>
215
216#include <bsls_assert.h>
217#include <bsls_review.h>
218
219#include <bsl_ctime.h> // 'bsl::tm'
220
221
222namespace bdlt {
223
224 // ===================
225 // struct DatetimeUtil
226 // ===================
227
228/// This utility `struct` provides a namespace for a suite of functions
229/// operating on objects of type `Datetime`.
231
232 public:
233 // CLASS METHODS
234
235 /// Load into the specified `result` the value of the specified
236 /// `timeStruct`. Return 0 on success, and a non-zero value with no
237 /// effect on `result` if `timeStruct` is invalid or otherwise cannot be
238 /// represented as a `Datetime`. Values in fields `tm_wday`, `tm_yday`,
239 /// and `tm_isdst` are ignored. The time 24:00:00 will be recognized,
240 /// and leap seconds (i.e., values in `tm_sec` of 60 or 61) which can
241 /// otherwise be represented as a `Datetime` will cause the conversion
242 /// to succeed with the `result` "rolling over" into the zeroth second
243 /// of next minute. Note that time zones are irrelevant for this
244 /// conversion.
245 static int convertFromTm(Datetime *result, const bsl::tm& timeStruct);
246
247 /// Return or load into the specified `result` the value of the
248 /// specified `datetime` expressed as a `bsl::tm`. Each field in the
249 /// result is set to its proper value except `tm_isdst`, which is set to
250 /// `-1` to indicate that no information on daylight saving time is
251 /// available. A time value of 24:00:00:00 will be converted to
252 /// 0:00:00. Note that time zones are irrelevant for this conversion.
253 static bsl::tm convertToTm( const Datetime& datetime);
254 static void convertToTm(bsl::tm *result, const Datetime& datetime);
255};
256
257// ============================================================================
258// INLINE DEFINITIONS
259// ============================================================================
260
261 // -------------------
262 // struct DatetimeUtil
263 // -------------------
264
265inline
267 const bsl::tm& timeStruct)
268{
269 BSLS_ASSERT(result);
270
271 bool isLeapSecond = false;
272 int seconds = timeStruct.tm_sec;
273
274 if (seconds > 59) {
275 // Start handling leap seconds by shifting to the previous non-leap
276 // second time.
277 isLeapSecond = true;
278 seconds = 59;
279 }
280
281 int rc = result->setDatetimeIfValid(timeStruct.tm_year + 1900,
282 timeStruct.tm_mon + 1,
283 timeStruct.tm_mday,
284 timeStruct.tm_hour,
285 timeStruct.tm_min,
286 seconds); // msec = 0
287
288 if (isLeapSecond && !rc) {
289 // Finish leap second handling by rolling over into second '0' in the
290 // next minute.
291 result->addSeconds(1);
292 }
293
294 return rc;
295}
296
297inline
298bsl::tm DatetimeUtil::convertToTm(const Datetime& datetime)
299{
300
301 // 'struct tm' may contain non POSIX standard fields (e.g., on Linux/OSX),
302 // which we want to 0 initialize.
303
304 bsl::tm result = bsl::tm();
305
306 result.tm_sec = datetime.second();
307 result.tm_min = datetime.minute();
308 const int hour = datetime.hour();
309 if (24 == hour) {
310 result.tm_hour = 0;
311 }
312 else {
313 result.tm_hour = hour;
314 }
315 result.tm_mday = datetime.day();
316 result.tm_mon = datetime.month() - 1;
317 result.tm_year = datetime.year() - 1900;
318 result.tm_wday = datetime.date().dayOfWeek() - 1;
319 result.tm_yday = datetime.date().dayOfYear() - 1;
320 result.tm_isdst = -1; // This information is unavailable.
321
322 return result;
323}
324
325inline
326void DatetimeUtil::convertToTm(bsl::tm *result, const Datetime& datetime)
327{
328 BSLS_ASSERT(result);
329
330 *result = convertToTm(datetime);
331}
332
333} // close package namespace
334
335
336#endif
337
338// ----------------------------------------------------------------------------
339// Copyright 2014 Bloomberg Finance L.P.
340//
341// Licensed under the Apache License, Version 2.0 (the "License");
342// you may not use this file except in compliance with the License.
343// You may obtain a copy of the License at
344//
345// http://www.apache.org/licenses/LICENSE-2.0
346//
347// Unless required by applicable law or agreed to in writing, software
348// distributed under the License is distributed on an "AS IS" BASIS,
349// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
350// See the License for the specific language governing permissions and
351// limitations under the License.
352// ----------------------------- END-OF-FILE ----------------------------------
353
354/** @} */
355/** @} */
356/** @} */
int dayOfYear() const
Return the day of the year in the range [1 .. 366] of this date.
Definition bdlt_date.h:940
DayOfWeek::Enum dayOfWeek() const
Definition bdlt_date.h:933
Definition bdlt_datetime.h:331
Date date() const
Return the value of the "date" part of this object.
Definition bdlt_datetime.h:2164
int year() const
Return the value of the year attribute of this object.
Definition bdlt_datetime.h:2289
int hour() const
Return the value of the hour attribute of this object.
Definition bdlt_datetime.h:2223
int minute() const
Return the value of the minute attribute of this object.
Definition bdlt_datetime.h:2249
int setDatetimeIfValid(int year, int month, int day, int hour=0, int minute=0, int second=0, int millisecond=0, int microsecond=0)
Definition bdlt_datetime.h:1432
Datetime & addSeconds(bsls::Types::Int64 seconds)
Definition bdlt_datetime.h:2024
int second() const
Return the value of the second attribute of this object.
Definition bdlt_datetime.h:2265
int month() const
Return the value of the month attribute of this object.
Definition bdlt_datetime.h:2259
int day() const
Definition bdlt_datetime.h:2172
#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_datetimeutil.h:230
static int convertFromTm(Datetime *result, const bsl::tm &timeStruct)
Definition bdlt_datetimeutil.h:266
static bsl::tm convertToTm(const Datetime &datetime)
Definition bdlt_datetimeutil.h:298