BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt_time.h
Go to the documentation of this file.
1/// @file bdlt_time.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlt_time.h -*-C++-*-
8#ifndef INCLUDED_BDLT_TIME
9#define INCLUDED_BDLT_TIME
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlt_time bdlt_time
15/// @brief Provide a value-semantic type representing time-of-day.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlt
19/// @{
20/// @addtogroup bdlt_time
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlt_time-purpose"> Purpose</a>
25/// * <a href="#bdlt_time-classes"> Classes </a>
26/// * <a href="#bdlt_time-description"> Description </a>
27/// * <a href="#bdlt_time-iso-standard-text-representation"> ISO Standard Text Representation </a>
28/// * <a href="#bdlt_time-usage"> Usage </a>
29/// * <a href="#bdlt_time-example-1-basic-bdlt-time-usage"> Example 1: Basic bdlt::Time Usage </a>
30///
31/// # Purpose {#bdlt_time-purpose}
32/// Provide a value-semantic type representing time-of-day.
33///
34/// # Classes {#bdlt_time-classes}
35///
36/// - bdlt::Time: time-of-day type (with microsecond resolution)
37///
38/// # Description {#bdlt_time-description}
39/// This component implements a value-semantic time class,
40/// `bdlt::Time`, that can represent the time of day to a resolution of one
41/// microsecond (using a 24-hour clock). Valid time values range from
42/// 00:00:00.000000 (i.e., midnight) through 23:59:59.999999 (i.e., one
43/// microsecond before midnight). A time value can be specified via five
44/// separate integer attribute values denoting hours `[0 .. 23]`, minutes
45/// `[0 .. 59]`, seconds `[0 .. 59]`, milliseconds `[0 .. 999]`, and
46/// microseconds `[0 .. 999]`. In addition, the `bdlt::Time` type has one more
47/// valid value, 24:00:00.000000, that can be set explicitly and accessed. The
48/// value 24:00:00.000000 behaves, in most cases, as if it were the value
49/// 00:00:00.000000; however, for all relational comparison operators,
50/// 24:00:00.000000 is not a valid argument and, therefore, would result in
51/// undefined behavior. Each of the `add` manipulators, along with modifying
52/// the value of the object, return the (signed) number of times that the
53/// 23:59:59.999999 - 00:00:00.000000 boundary was crossed in performing the
54/// addition.
55///
56/// ## ISO Standard Text Representation {#bdlt_time-iso-standard-text-representation}
57///
58///
59/// A common standard text representation of a date and time value is described
60/// by ISO 8601. BDE provides the @ref bdlt_iso8601util component for conversion
61/// to and from the standard ISO8601 format.
62///
63/// ## Usage {#bdlt_time-usage}
64///
65///
66/// This section illustrates intended use of this component.
67///
68/// ### Example 1: Basic bdlt::Time Usage {#bdlt_time-example-1-basic-bdlt-time-usage}
69///
70///
71/// This example demonstrates how to create and use a `bdlt::Time` object.
72///
73/// First, create an object `t1` having the default value, and then verify that
74/// it represents the value 24:00:00.000000:
75/// @code
76/// bdlt::Time t1; assert(24 == t1.hour());
77/// assert( 0 == t1.minute());
78/// assert( 0 == t1.second());
79/// assert( 0 == t1.millisecond());
80/// assert( 0 == t1.microsecond());
81/// @endcode
82/// Then, set `t1` to the value 2:34pm (14:34:00.000000):
83/// @code
84/// t1.setTime(14, 34); assert(14 == t1.hour());
85/// assert(34 == t1.minute());
86/// assert( 0 == t1.second());
87/// assert( 0 == t1.millisecond());
88/// assert( 0 == t1.microsecond());
89/// @endcode
90/// Next, use `setTimeIfValid` to attempt to assign the invalid value 24:15 to
91/// `t1`, then verify the method returns an error status and the value of `t1`
92/// is unmodified:
93/// @code
94/// int ret = t1.setTimeIfValid(24, 15);
95/// assert( 0 != ret); // 24:15 is not
96/// // valid
97///
98/// assert(14 == t1.hour()); // no effect
99/// assert(34 == t1.minute()); // on the
100/// assert( 0 == t1.second()); // object
101/// assert( 0 == t1.millisecond());
102/// assert( 0 == t1.microsecond());
103/// @endcode
104/// Then, create `t2` as a copy of `t1`:
105/// @code
106/// bdlt::Time t2(t1); assert(t1 == t2);
107/// @endcode
108/// Next, add 5 minutes and 7 seconds to the value of `t2` (in two steps), and
109/// confirm the value of `t2`:
110/// @code
111/// t2.addMinutes(5);
112/// t2.addSeconds(7);
113/// assert(14 == t2.hour());
114/// assert(39 == t2.minute());
115/// assert( 7 == t2.second());
116/// assert( 0 == t2.millisecond());
117/// assert( 0 == t2.microsecond());
118/// @endcode
119/// Then, subtract `t1` from `t2` to yield a `bdlt::DatetimeInterval` `dt`
120/// representing the time-interval between those two times, and verify the value
121/// of `dt` is 5 minutes and 7 seconds (or 307 seconds):
122/// @code
123/// bdlt::DatetimeInterval dt = t2 - t1;
124/// assert(307 == dt.totalSeconds());
125/// @endcode
126/// Finally, stream the value of `t2` to `stdout`:
127/// @code
128/// bsl::cout << t2 << bsl::endl;
129/// @endcode
130/// The streaming operator produces the following output on `stdout`:
131/// @code
132/// 14:39:07.000000
133/// @endcode
134/// @}
135/** @} */
136/** @} */
137
138/** @addtogroup bdl
139 * @{
140 */
141/** @addtogroup bdlt
142 * @{
143 */
144/** @addtogroup bdlt_time
145 * @{
146 */
147
148#include <bdlscm_version.h>
149
151#include <bdlt_timeunitratio.h>
152
153#include <bdlb_bitutil.h>
154
155#include <bslh_hash.h>
156
159
160#include <bsls_assert.h>
161#include <bsls_atomic.h>
162#include <bsls_log.h>
163#include <bsls_performancehint.h>
164#include <bsls_platform.h>
165#include <bsls_review.h>
167#include <bsls_types.h>
168
169#include <bsl_iosfwd.h>
170#include <bsl_cstring.h> // memset
171#include <bsl_sstream.h>
172
173
174namespace bdlt {
175
176 // ==========
177 // class Time
178 // ==========
179
180/// This class implements a value-semantic type that represents the time of
181/// day to a resolution of one microsecond. Each object of this (almost)
182/// simply constrained attribute class *always* represents a valid time
183/// value to a resolution of one microsecond. The valid range for times is
184/// 00:00:00.000000 through 23:59:59.999999, except that 24:00:00.000000
185/// represents the default-constructed value. The value 24:00:00.000000
186/// behaves, in most cases, as if it were the value 00:00:00.000000;
187/// however, for all relational comparison operators, 24:00:00.000000 is not
188/// a valid argument and, therefore, would result in undefined behavior.
189/// Each add operation on a `Time` object returns the (signed) number of
190/// times that the 23:59:59.999999 - 00:00:00.000000 boundary was crossed
191/// while performing the operation. Attempting to construct a `Time` with
192/// any attribute outside its valid range (or with an hour attribute value
193/// of 24 and any other attribute non-zero) has undefined behavior.
194///
195/// See @ref bdlt_time
196class Time {
197
198 // PRIVATE TYPES
199 enum {
200 k_DEFAULT_FRACTIONAL_SECOND_PRECISION = 6
201 };
202
203 // CLASS DATA
204 static const bsls::Types::Int64 k_REP_MASK = 0x0000004000000000ULL;
205
206 static bsls::AtomicInt64 s_invalidRepresentationCount;
207
208 // DATA
209 bsls::Types::Int64 d_value; // encoded offset from 00:00:00.000000
210
211 // FRIENDS
212 friend DatetimeInterval operator-(const Time&, const Time&);
213 friend bool operator==(const Time&, const Time&);
214 friend bool operator!=(const Time&, const Time&);
215 friend bool operator< (const Time&, const Time&);
216 friend bool operator<=(const Time&, const Time&);
217 friend bool operator>=(const Time&, const Time&);
218 friend bool operator> (const Time&, const Time&);
219 template <class HASHALG>
220 friend void hashAppend(HASHALG& hashAlg, const Time&);
221
222 // PRIVATE MANIPULATORS
223
224 /// Assign to `d_value` the representation of time such that the
225 /// difference between this representation of time and 00:00:00.000000
226 /// is the specified `totalMicroseconds`. If
227 /// `TimeUnitRatio::k_US_PER_D == totalMicroseconds`, assign to
228 /// `d_value` the representation of 24:00:00.000000. The behavior is
229 /// undefined unless
230 /// `0 <= totalMicroseconds <= TimeUnitRatio::k_US_PER_D`.
231 void setMicrosecondsFromMidnight(bsls::Types::Int64 totalMicroseconds);
232
233 // PRIVATE ACCESSORS
234
235 /// Return the difference, in microseconds, between the value of this
236 /// object and 00:00:00.000000. If the value of this object is
237 /// 24:00:00.000000, it is treated as 00:00:00.000000.
238 bsls::Types::Int64 microsecondsFromMidnight() const;
239
240 /// Invoke a review failure notifying that a `bdlt::Time` instance is
241 /// being used in an invalid state. The behavior is undefined unless
242 /// this object has the old represenation (`k_REP_MASK > d_value`) and
243 /// `BSLS_ASSERT_SAFE` is not active.
244 bsls::Types::Int64 invalidMicrosecondsFromMidnight() const;
245
246 /// If `d_value` was stored using the current representation scheme,
247 /// return `d_value`. Otherwise, return the representation of the time
248 /// corresponding to `d_value` total milliseconds since 00:00:00.000000
249 /// (i.e., convert from the old representation scheme to the current
250 /// scheme), or return the current representation of 24:00:00.000000 if
251 /// `d_value` is the old representation of the default-constructed
252 /// value.
253 bsls::Types::Int64 updatedRepresentation() const;
254
255 public:
256 // CLASS METHODS
257
258 /// Return `true` if the specified `hour`, and the optionally specified
259 /// `minute`, `second`, `millisecond`, and `microsecond`, represent a
260 /// valid `Time` value, and `false` otherwise. Unspecified arguments
261 /// default to 0. The `hour`, `minute`, `second`, `millisecond`, and
262 /// `microsecond` attributes comprise a valid `Time` value if
263 /// `0 <= hour < 24`, `0 <= minute < 60`, `0 <= second < 60`,
264 /// `0 <= millisecond < 1000`, and `0 <= microsecond < 1000`.
265 /// Additionally, 24:00:00.000000 also represents a valid `Time` value.
266 static bool isValid(int hour,
267 int minute = 0,
268 int second = 0,
269 int millisecond = 0,
270 int microsecond = 0);
271
272 // Aspects
273
274 /// Return the maximum valid BDEX format version, as indicated by the
275 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
276 /// method. Note that it is highly recommended that `versionSelector`
277 /// be formatted as "YYYYMMDD", a date representation. Also note that
278 /// `versionSelector` should be a *compile*-time-chosen value that
279 /// selects a format version supported by both externalizer and
280 /// unexternalizer. See the `bslx` package-level documentation for more
281 /// information on BDEX streaming of value-semantic types and
282 /// containers.
283 static int maxSupportedBdexVersion(int versionSelector);
284
285 // CREATORS
286
287 /// Create a `Time` object having the value 24:00:00.000000.
288 Time();
289
290 /// Create a `Time` object having the (valid) value represented by the
291 /// specified `hour`, and the optionally specified `minute`, `second`,
292 /// `millisecond`, and `microsecond`. Unspecified arguments default to
293 /// 0. The behavior is undefined unless all of the specified values are
294 /// within their valid ranges (see `isValid`).
295 explicit
296 Time(int hour,
297 int minute = 0,
298 int second = 0,
299 int millisecond = 0,
300 int microsecond = 0);
301
302 /// Create a `Time` object having the value of the specified `original`
303 /// time.
304 Time(const Time& original);
305
306 /// Destroy this 'Time' object.
307 ~Time() = default;
308
309 // MANIPULATORS
310
311 /// Assign to this time object the value of the specified `rhs` object,
312 /// and return a reference providing modifiable access to this object.
313 Time& operator=(const Time& rhs);
314
315 /// Add to this time object the value of the specified `rhs` datetime
316 /// interval, and return a reference providing modifiable access to this
317 /// object.
318 Time& operator+=(const DatetimeInterval& rhs);
319
320 /// Subtract from this time object the value of the specified `rhs`
321 /// datetime interval, and return a reference providing modifiable
322 /// access to this object.
323 Time& operator-=(const DatetimeInterval& rhs);
324
325 /// Increase the value of this time object by the specified number of
326 /// `hours`, and return the (signed) number of times that the
327 /// 23:59:59.999999 - 00:00:00.000000 boundary was crossed in performing
328 /// the operation. Note that `hours` may be negative.
329 int addHours(int hours);
330
331 /// Increase the value of this time object by the specified number of
332 /// `minutes`, and return the (signed) number of times that the
333 /// 23:59:59.999999 - 00:00:00.000000 boundary was crossed in performing
334 /// the operation. Note that `minutes` may be negative.
335 int addMinutes(int minutes);
336
337 /// Increase the value of this time object by the specified number of
338 /// `seconds`, and return the (signed) number of times that the
339 /// 23:59:59.999999 - 00:00:00.000000 boundary was crossed in performing
340 /// the operation. Note that `seconds` may be negative.
341 int addSeconds(int seconds);
342
343 /// Increase the value of this time object by the specified number of
344 /// `milliseconds`, and return the (signed) number of times that the
345 /// 23:59:59.999999 - 00:00:00.000000 boundary was crossed in performing
346 /// the operation. Note that `milliseconds` may be negative.
347 int addMilliseconds(int milliseconds);
348
349 /// Increase the value of this time object by the specified number of
350 /// `microseconds`, and return the (signed) number of times that the
351 /// 23:59:59.999999 - 00:00:00.000000 boundary was crossed in performing
352 /// the operation. Note that `microseconds` may be negative.
354
355 /// Increase the value of this time object by the specified `interval`
356 /// of time, and return the (signed) number of times that the
357 /// 23:59:59.999999 - 00:00:00.000000 boundary was crossed in performing
358 /// the operation. The behavior is undefined unless the number of
359 /// crossings that would be returned can be represented by an `int`.
360 int addInterval(const DatetimeInterval& interval);
361
362 /// Add to the value of this time object the specified (signed) number
363 /// of `hours`, and the optionally specified (signed) numbers of
364 /// `minutes`, `seconds`, `milliseconds`, and `microseconds`; return the
365 /// (signed) number of times that the 23:59:59.999999 -
366 /// 00:00:00.000000 boundary was crossed in performing the operation.
367 /// Unspecified arguments default to 0.
368 int addTime(int hours,
369 int minutes = 0,
370 int seconds = 0,
371 int milliseconds = 0,
372 bsls::Types::Int64 microseconds = 0);
373
374 /// Set the "hour" attribute of this time object to the specified
375 /// `hour`; if `hour` is 24, set the remaining attributes of this object
376 /// to 0. The behavior is undefined unless `0 <= hour <= 24`.
377 void setHour(int hour);
378
379 /// Set the "hour" attribute of this time object to the specified `hour`
380 /// value *if* `0 <= hour <= 24`. If `24 == hour`, set the remaining
381 /// attributes to 0. Return 0 on success, and a non-zero value (with no
382 /// effect) otherwise.
383 int setHourIfValid(int hour);
384
385 /// Set the "minute" attribute of this time object to the specified
386 /// `minute`; if the `hour` attribute is 24, set the `hour` attribute to
387 /// 0. The behavior is undefined unless `0 <= minute < 60`.
388 void setMinute(int minute);
389
390 /// Set the "minute" attribute of this time object to the specified
391 /// `minute` *if* `0 <= minute < 60`; if the `hour` attribute is 24, set
392 /// the `hour` attribute to 0. Return 0 on success, and a non-zero
393 /// value (with no effect) otherwise.
394 int setMinuteIfValid(int minute);
395
396 /// Set the "second" attribute of this time object to the specified
397 /// `second`; if the `hour` attribute is 24, set the `hour` attribute to
398 /// 0. The behavior is undefined unless `0 <= second < 60`.
399 void setSecond(int second);
400
401 /// Set the "second" attribute of this time object to the specified
402 /// `second` *if* `0 <= second < 60`; if the `hour` attribute is 24, set
403 /// the `hour` attribute to 0. Return 0 on success, and a non-zero
404 /// value (with no effect) otherwise.
405 int setSecondIfValid(int second);
406
407 /// Set the "millisecond" attribute of this time object to the specified
408 /// `millisecond`; if the `hour` attribute is 24, set the `hour`
409 /// attribute to 0. The behavior is undefined unless
410 /// `0 <= millisecond < 1000`.
412
413 /// Set the "millisecond" attribute of this time object to the specified
414 /// `millisecond` *if* `0 <= millisecond < 1000`; if the `hour`
415 /// attribute is 24, set the `hour` attribute to 0. Return 0 on
416 /// success, and a non-zero value (with no effect) otherwise.
418
419 /// Set the "microsecond" attribute of this time object to the specified
420 /// `microsecond`; if the `hour` attribute is 24, set the `hour`
421 /// attribute to 0. The behavior is undefined unless
422 /// `0 <= microsecond < 1000`.
424
425 /// Set the "microsecond" attribute of this time object to the specified
426 /// `microsecond` *if* `0 <= microsecond < 1000`; if the `hour`
427 /// attribute is 24, set the `hour` attribute to 0. Return 0 on
428 /// success, and a non-zero value (with no effect) otherwise.
430
431 /// Set the value of this time object to the specified `hour`, and the
432 /// optionally specified `minute`, `second`, `millisecond`, and
433 /// `microsecond`. Unspecified arguments default to 0. The behavior is
434 /// undefined unless all of the specified values are within their valid
435 /// ranges (see `isValid`).
436 void setTime(int hour,
437 int minute = 0,
438 int second = 0,
439 int millisecond = 0,
440 int microsecond = 0);
441
442 /// Set the value of this time object to the specified `hour`, and the
443 /// optionally specified `minute`, `second`, `millisecond`, and
444 /// `microsecond`, if they would comprise a valid `Time` value (see
445 /// `isValid`). Return 0 on success, and a non-zero value (with no
446 /// effect) otherwise. Unspecified arguments default to 0.
447 int setTimeIfValid(int hour,
448 int minute = 0,
449 int second = 0,
450 int millisecond = 0,
451 int microsecond = 0);
452
453 // Aspects
454
455 /// Assign to this object the value read from the specified input
456 /// `stream` using the specified `version` format, and return a
457 /// reference to `stream`. If `stream` is initially invalid, this
458 /// operation has no effect. If `version` is not supported, this object
459 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
460 /// If `version` is supported but `stream` becomes invalid during this
461 /// operation, this object has an undefined, but valid, state. Note
462 /// that no version is read from `stream`. See the `bslx` package-level
463 /// documentation for more information on BDEX streaming of
464 /// value-semantic types and containers.
465 template <class STREAM>
466 STREAM& bdexStreamIn(STREAM& stream, int version);
467
468 // ACCESSORS
469
470 /// Load, into the specified `hour`, and the optionally specified
471 /// `minute`, `second`, `millisecond`, and `microsecond`, the respective
472 /// `hour`, `minute`, `second`, `millisecond`, and `microsecond`
473 /// attribute values from this time object. Unspecified arguments
474 /// default to 0. Supplying 0 for an address argument suppresses the
475 /// loading of the value for the corresponding attribute, but has no
476 /// effect on the loading of other attribute values.
477 void getTime(int *hour,
478 int *minute = 0,
479 int *second = 0,
480 int *millisecond = 0,
481 int *microsecond = 0) const;
482
483 /// Return the value of the `hour` attribute of this time object.
484 int hour() const;
485
486 /// Return the value of the `minute` attribute of this time object.
487 int minute() const;
488
489 /// Return the value of the `second` attribute of this time object.
490 int second() const;
491
492 /// Return the value of the `millisecond` attribute of this time object.
493 int millisecond() const;
494
495 /// Return the value of the `microsecond` attribute of this time object.
496 int microsecond() const;
497
498 /// Efficiently write to the specified `result` buffer no more than the
499 /// specified `numBytes` of a representation of the value of this
500 /// object. Optionally specify `fractionalSecondPrecision` digits to
501 /// indicate how many fractional second digits to output. If
502 /// `fractionalSecondPrecision` is not specified then 6 fractional
503 /// second digits will be output (3 digits for milliseconds and 3 digits
504 /// for microseconds). Return the number of characters (not including
505 /// the null character) that would have been written if the limit due to
506 /// `numBytes` were not imposed. `result` is null-terminated unless
507 /// `numBytes` is 0. The behavior is undefined unless `0 <= numBytes`,
508 /// `0 <= fractionalSecondPrecision <= 6`, and `result` refers to at
509 /// least `numBytes` contiguous bytes. Note that the return value is
510 /// greater than or equal to `numBytes` if the output representation was
511 /// truncated to avoid `result` overrun.
512 int printToBuffer(char *result,
513 int numBytes,
514 int fractionalSecondPrecision = 6) const;
515
516 // Aspects
517
518 /// Write the value of this object, using the specified `version`
519 /// format, to the specified output `stream`, and return a reference to
520 /// `stream`. If `stream` is initially invalid, this operation has no
521 /// effect. If `version` is not supported, `stream` is invalidated, but
522 /// otherwise unmodified. Note that `version` is not written to
523 /// `stream`. See the `bslx` package-level documentation for more
524 /// information on BDEX streaming of value-semantic types and
525 /// containers.
526 template <class STREAM>
527 STREAM& bdexStreamOut(STREAM& stream, int version) const;
528
529 /// Write the value of this object to the specified output `stream` in a
530 /// human-readable format, and return a reference to `stream`.
531 /// Optionally specify an initial indentation `level`, whose absolute
532 /// value is incremented recursively for nested objects. If `level` is
533 /// specified, optionally specify `spacesPerLevel`, whose absolute value
534 /// indicates the number of spaces per indentation level for this and
535 /// all of its nested objects. If `level` is negative, suppress
536 /// indentation of the first line. If `spacesPerLevel` is negative,
537 /// format the entire output on one line, suppressing all but the
538 /// initial indentation (as governed by `level`). If `stream` is not
539 /// valid on entry, this operation has no effect. Note that this
540 /// human-readable format is not fully specified, and can change without
541 /// notice.
542 bsl::ostream& print(bsl::ostream& stream,
543 int level = 0,
544 int spacesPerLevel = 4) const;
545
546#ifndef BDE_OPENSOURCE_PUBLICATION // pending deprecation
547
548 // DEPRECATED METHODS
549
550 /// @deprecated Use @ref maxSupportedBdexVersion(int) instead.
551 ///
552 /// Return the most current BDEX streaming version number supported by
553 /// this class.
554 static int maxSupportedBdexVersion();
555
556#endif // BDE_OPENSOURCE_PUBLICATION -- pending deprecation
557#ifndef BDE_OMIT_INTERNAL_DEPRECATED // BDE2.22
558
559 /// @deprecated Use @ref maxSupportedBdexVersion(int) instead.
560 ///
561 /// Return the most current BDEX streaming version number supported by
562 /// this class.
563 static int maxSupportedVersion();
564
565 /// @deprecated Use @ref print instead.
566 ///
567 /// Format this time to the specified output `stream`, and return a
568 /// reference to the modifiable `stream`.
569 bsl::ostream& streamOut(bsl::ostream& stream) const;
570
571 /// @deprecated Use @ref setTimeIfValid instead.
572 ///
573 /// Set the value of this time object to the specified `hour`, and the
574 /// optionally specified `minute`, `second`, and `millisecond`, if they
575 /// would comprise a valid `Time` value (see `isValid`). Return 0 on
576 /// success, and a non-zero value (with no effect) otherwise.
577 /// Unspecified arguments default to 0.
578 int validateAndSetTime(int hour,
579 int minute = 0,
580 int second = 0,
581 int millisecond = 0);
582
583#endif // BDE_OMIT_INTERNAL_DEPRECATED -- BDE2.22
584
585};
586
587// FREE OPERATORS
588
589/// Pass the specified `object` to the specified `hashAlg`. This function
590/// integrates with the `bslh` modular hashing system and effectively
591/// provides a `bsl::hash` specialization for `Time`.
592template <class HASHALG>
593void hashAppend(HASHALG& hashAlg, const Time& object);
594
595/// Return a `Time` value that is the sum of the specified `lhs` time and
596/// the specified `rhs` datetime interval.
597Time operator+(const Time& lhs, const DatetimeInterval& rhs);
598
599/// Return a `Time` value that is the sum of the specified `lhs` datetime
600/// interval and the specified `rhs` time.
601Time operator+(const DatetimeInterval& lhs, const Time& rhs);
602
603/// Return a `Time` value that is the difference between the specified `lhs`
604/// time and the specified `rhs` datetime interval.
605Time operator-(const Time& lhs, const DatetimeInterval& rhs);
606
607/// Return a `DatetimeInterval` object initialized with the difference
608/// between the specified `lhs` and `rhs` time values.
609DatetimeInterval operator-(const Time& lhs, const Time& rhs);
610
611/// Return `true` if the specified `lhs` and `rhs` time objects have the
612/// same value, and `false` otherwise. Two time objects have the same value
613/// if each of their corresponding `hour`, `minute`, `second`,
614/// `millisecond`, and `microsecond` attributes respectively have the same
615/// value.
616bool operator==(const Time& lhs, const Time& rhs);
617
618/// Return `true` if the specified `lhs` and `rhs` time objects do not have
619/// the same value, and `false` otherwise. Two time objects do not have the
620/// same value if any of their corresponding `hour`, `minute`, `second`,
621/// `millisecond`, and `microsecond` attributes respectively do not have the
622/// same value.
623bool operator!=(const Time& lhs, const Time& rhs);
624
625/// Return `true` if the specified `lhs` time value is less than the
626/// specified `rhs` time value, and `false` otherwise. The behavior is
627/// undefined unless `lhs != Time()` and `rhs != Time()` (i.e., they do not
628/// have the, default, value 24:00:00.000000).
629bool operator<(const Time& lhs, const Time& rhs);
630
631/// Return `true` if the specified `lhs` time value is less than or equal to
632/// the specified `rhs` time value, and `false` otherwise. The behavior is
633/// undefined unless `lhs != Time()` and `rhs != Time()` (i.e., they do not
634/// have the, default, value 24:00:00.000000).
635bool operator<=(const Time& lhs, const Time& rhs);
636
637/// Return `true` if the specified `lhs` time value is greater than the
638/// specified `rhs` time value, and `false` otherwise. The behavior is
639/// undefined unless `lhs != Time()` and `rhs != Time()` (i.e., they do not
640/// have the, default, value 24:00:00.000000).
641bool operator>(const Time& lhs, const Time& rhs);
642
643/// Return `true` if the specified `lhs` time value is greater than or equal
644/// to the specified `rhs` time value, and `false` otherwise. The behavior
645/// is undefined unless `lhs != Time()` and `rhs != Time()` (i.e., they do
646/// not have the, default, value 24:00:00.000000).
647bool operator>=(const Time& lhs, const Time& rhs);
648
649/// Write the value of the specified `time` object to the specified output
650/// `stream` in a single-line format, and return a reference to `stream`.
651/// If `stream` is not valid on entry, this operation has no effect. Note
652/// that this human-readable format is not fully specified, can change
653/// without notice, and is logically equivalent to:
654/// @code
655/// print(stream, 0, -1);
656/// @endcode
657bsl::ostream& operator<<(bsl::ostream& stream, const Time& time);
658
659// ============================================================================
660// INLINE DEFINITIONS
661// ============================================================================
662
663 // ----------
664 // class Time
665 // ----------
666
667// PRIVATE MANIPULATORS
668inline
669void Time::setMicrosecondsFromMidnight(bsls::Types::Int64 totalMicroseconds)
670{
671 BSLS_REVIEW( 0 <= totalMicroseconds);
672 BSLS_REVIEW(TimeUnitRatio::k_US_PER_D >= totalMicroseconds);
673
674 d_value = totalMicroseconds | k_REP_MASK;
675}
676
677// PRIVATE ACCESSORS
678inline
679bsls::Types::Int64 Time::microsecondsFromMidnight() const
680{
681 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(k_REP_MASK > d_value)) {
683 return invalidMicrosecondsFromMidnight(); // RETURN
684 }
685
686 return d_value & (~k_REP_MASK);
687}
688
689inline
690bsls::Types::Int64 Time::updatedRepresentation() const
691{
692 return microsecondsFromMidnight() | k_REP_MASK;
693}
694
695// CLASS METHODS
696inline
697bool Time::isValid(int hour,
698 int minute,
699 int second,
700 int millisecond,
701 int microsecond)
702{
703 return (0 <= hour && hour < bdlt::TimeUnitRatio::k_H_PER_D_32 &&
711 0 == minute &&
712 0 == second &&
713 0 == millisecond &&
714 0 == microsecond);
715}
716
717 // Aspects
718
719inline
720int Time::maxSupportedBdexVersion(int versionSelector)
721{
722 if (versionSelector >= 20170401) {
723 return 2; // RETURN
724 }
725 return 1;
726}
727
728// CREATORS
729inline
731: d_value(TimeUnitRatio::k_US_PER_D | k_REP_MASK)
732{
733}
734
735inline
736Time::Time(int hour, int minute, int second, int millisecond, int microsecond)
737{
739
740 setMicrosecondsFromMidnight( TimeUnitRatio::k_US_PER_H * hour
744 + microsecond);
745}
746
747inline
748Time::Time(const Time& original)
749: d_value(original.d_value)
750{
751 d_value = updatedRepresentation();
752}
753
754// MANIPULATORS
755inline
757{
758 d_value = rhs.d_value;
759 d_value = updatedRepresentation();
760
761 return *this;
762}
763
764inline
766{
767 addInterval(rhs);
768 return *this;
769}
770
771inline
773{
774 addInterval(-rhs);
775 return *this;
776}
777
778inline
780{
781 enum { k_SUCCESS = 0, k_FAILURE = -1 };
782
783 if (0 <= hour && hour <= 24) {
784 setHour(hour);
785 return k_SUCCESS; // RETURN
786 }
787 return k_FAILURE;
788}
789
790inline
791int Time::setMicrosecondIfValid(int microsecond)
792{
793 enum { k_SUCCESS = 0, k_FAILURE = -1 };
794
795 if (0 <= microsecond && microsecond <= 999) {
797 return k_SUCCESS; // RETURN
798 }
799 return k_FAILURE;
800}
801
802inline
803int Time::setMillisecondIfValid(int millisecond)
804{
805 enum { k_SUCCESS = 0, k_FAILURE = -1 };
806
807 if (0 <= millisecond && millisecond <= 999) {
809 return k_SUCCESS; // RETURN
810 }
811 return k_FAILURE;
812}
813
814inline
816{
817 enum { k_SUCCESS = 0, k_FAILURE = -1 };
818
819 if (0 <= minute && minute <= 59) {
821 return k_SUCCESS; // RETURN
822 }
823 return k_FAILURE;
824}
825
826inline
828{
829 enum { k_SUCCESS = 0, k_FAILURE = -1 };
830
831 if (0 <= second && second <= 59) {
833 return k_SUCCESS; // RETURN
834 }
835 return k_FAILURE;
836}
837
838inline
840 int minute,
841 int second,
842 int millisecond,
843 int microsecond)
844{
845 enum { k_SUCCESS = 0, k_FAILURE = -1 };
846
849 return k_SUCCESS; // RETURN
850 }
851
852 return k_FAILURE;
853}
854
855 // Aspects
856
857template <class STREAM>
858STREAM& Time::bdexStreamIn(STREAM& stream, int version)
859{
860 if (stream) {
861 switch (version) { // switch on the schema version
862 case 2: {
863 bsls::Types::Int64 tmp = 0;
864 stream.getInt64(tmp);
865
866 if ( stream
867 && 0 <= tmp
868 && TimeUnitRatio::k_US_PER_D >= tmp) {
869 setMicrosecondsFromMidnight(tmp);
870 }
871 else {
872 stream.invalidate();
873 }
874 } break;
875 case 1: {
876 int tmp = 0;
877 stream.getInt32(tmp);
878
879 if ( stream
880 && static_cast<unsigned int>(tmp) <=
881 static_cast<unsigned int>(TimeUnitRatio::k_MS_PER_D_32)) {
882 setMicrosecondsFromMidnight(TimeUnitRatio::k_US_PER_MS * tmp);
883 }
884 else {
885 stream.invalidate();
886 }
887 } break;
888 default: {
889 stream.invalidate(); // unrecognized version number
890 }
891 }
892 }
893 return stream;
894}
895
896// ACCESSORS
897inline
898int Time::hour() const
899{
900 return static_cast<int>(microsecondsFromMidnight()
902}
903
904inline
906{
907 return static_cast<int>( microsecondsFromMidnight()
909}
910
911inline
913{
914 return static_cast<int>( microsecondsFromMidnight()
917}
918
919inline
920int Time::minute() const
921{
922 return static_cast<int>( microsecondsFromMidnight()
925}
926
927inline
928int Time::second() const
929{
930 return static_cast<int>( microsecondsFromMidnight()
933}
934
935 // Aspects
936
937template <class STREAM>
938STREAM& Time::bdexStreamOut(STREAM& stream, int version) const
939{
940 if (stream) {
941 switch (version) { // switch on the schema version
942 case 2: {
943 stream.putInt64(microsecondsFromMidnight());
944 } break;
945 case 1: {
946 stream.putInt32(static_cast<int>(microsecondsFromMidnight()
948 } break;
949 default: {
950 stream.invalidate(); // unrecognized version number
951 }
952 }
953 }
954 return stream;
955}
956
957#ifndef BDE_OPENSOURCE_PUBLICATION // pending deprecation
958
959// DEPRECATED METHODS
960inline
965
966#endif // BDE_OPENSOURCE_PUBLICATION -- pending deprecation
967#ifndef BDE_OMIT_INTERNAL_DEPRECATED // BDE2.22
968inline
973
974inline
975bsl::ostream& Time::streamOut(bsl::ostream& stream) const
976{
977 return stream << *this;
978}
979
980inline
981int Time::validateAndSetTime(int hour, int minute, int second, int millisecond)
982{
984}
985
986#endif // BDE_OMIT_INTERNAL_DEPRECATED -- BDE2.22
987
988} // close package namespace
989
990// FREE OPERATORS
991inline
992bdlt::Time bdlt::operator+(const Time& lhs, const DatetimeInterval& rhs)
993{
994 Time result(lhs);
995 return result += rhs;
996}
997
998inline
999bdlt::Time bdlt::operator+(const DatetimeInterval& lhs, const Time& rhs)
1000{
1001 Time result(rhs);
1002 return result += lhs;
1003}
1004
1005inline
1006bdlt::Time bdlt::operator-(const Time& lhs, const DatetimeInterval& rhs)
1007{
1008 Time result(lhs);
1009 return result -= rhs;
1010}
1011
1012inline
1013bdlt::DatetimeInterval bdlt::operator-(const Time& lhs, const Time& rhs)
1014{
1015 DatetimeInterval timeInterval;
1016
1017 timeInterval.setTotalMicroseconds(
1018 lhs.microsecondsFromMidnight() % bdlt::TimeUnitRatio::k_US_PER_D
1019 - rhs.microsecondsFromMidnight() % bdlt::TimeUnitRatio::k_US_PER_D);
1020
1021 return timeInterval;
1022}
1023
1024inline
1025bool bdlt::operator==(const Time& lhs, const Time& rhs)
1026{
1027 bsls::Types::Int64 lhsValue = lhs.microsecondsFromMidnight();
1028 bsls::Types::Int64 rhsValue = rhs.microsecondsFromMidnight();
1029
1030 return lhsValue == rhsValue;
1031}
1032
1033inline
1034bool bdlt::operator!=(const Time& lhs, const Time& rhs)
1035{
1036 bsls::Types::Int64 lhsValue = lhs.microsecondsFromMidnight();
1037 bsls::Types::Int64 rhsValue = rhs.microsecondsFromMidnight();
1038
1039 return lhsValue != rhsValue;
1040}
1041
1042inline
1043bool bdlt::operator<(const Time& lhs, const Time& rhs)
1044{
1046 != lhs.microsecondsFromMidnight());
1048 != rhs.microsecondsFromMidnight());
1049
1050 bsls::Types::Int64 lhsValue = lhs.microsecondsFromMidnight();
1051 bsls::Types::Int64 rhsValue = rhs.microsecondsFromMidnight();
1052
1053 return lhsValue < rhsValue;
1054}
1055
1056inline
1057bool bdlt::operator<=(const Time& lhs, const Time& rhs)
1058{
1060 != lhs.microsecondsFromMidnight());
1062 != rhs.microsecondsFromMidnight());
1063
1064 bsls::Types::Int64 lhsValue = lhs.microsecondsFromMidnight();
1065 bsls::Types::Int64 rhsValue = rhs.microsecondsFromMidnight();
1066
1067 return lhsValue <= rhsValue;
1068}
1069
1070inline
1071bool bdlt::operator>(const Time& lhs, const Time& rhs)
1072{
1074 != lhs.microsecondsFromMidnight());
1076 != rhs.microsecondsFromMidnight());
1077
1078 bsls::Types::Int64 lhsValue = lhs.microsecondsFromMidnight();
1079 bsls::Types::Int64 rhsValue = rhs.microsecondsFromMidnight();
1080
1081 return lhsValue > rhsValue;
1082}
1083
1084inline
1085bool bdlt::operator>=(const Time& lhs, const Time& rhs)
1086{
1088 != lhs.microsecondsFromMidnight());
1090 != rhs.microsecondsFromMidnight());
1091
1092 bsls::Types::Int64 lhsValue = lhs.microsecondsFromMidnight();
1093 bsls::Types::Int64 rhsValue = rhs.microsecondsFromMidnight();
1094
1095 return lhsValue >= rhsValue;
1096}
1097
1098inline
1099bsl::ostream& bdlt::operator<<(bsl::ostream& stream, const Time& time)
1100{
1101 return time.print(stream, 0, -1);
1102}
1103
1104// FREE FUNCTIONS
1105template <class HASHALG>
1106inline
1107void bdlt::hashAppend(HASHALG& hashAlg, const Time& object)
1108{
1109 using ::BloombergLP::bslh::hashAppend;
1110 hashAppend(hashAlg, object.microsecondsFromMidnight());
1111}
1112
1113namespace bslmf {
1114
1115// TRAITS
1116
1117/// This template specialization for `IsBitwiseCopyable` indicates that
1118/// `bdlt::Time` is a bitwise copyable type.
1119template <>
1120struct IsBitwiseCopyable<BloombergLP::bdlt::Time> : bsl::true_type {
1121};
1122
1123} // close namespace bslmf
1124
1125
1126#endif
1127
1128// ----------------------------------------------------------------------------
1129// Copyright 2017 Bloomberg Finance L.P.
1130//
1131// Licensed under the Apache License, Version 2.0 (the "License");
1132// you may not use this file except in compliance with the License.
1133// You may obtain a copy of the License at
1134//
1135// http://www.apache.org/licenses/LICENSE-2.0
1136//
1137// Unless required by applicable law or agreed to in writing, software
1138// distributed under the License is distributed on an "AS IS" BASIS,
1139// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1140// See the License for the specific language governing permissions and
1141// limitations under the License.
1142// ----------------------------- END-OF-FILE ----------------------------------
1143
1144/** @} */
1145/** @} */
1146/** @} */
Definition bdlt_datetimeinterval.h:201
Definition bdlt_time.h:196
static int maxSupportedBdexVersion()
Definition bdlt_time.h:961
friend bool operator!=(const Time &, const Time &)
int setMicrosecondIfValid(int microsecond)
Definition bdlt_time.h:791
void getTime(int *hour, int *minute=0, int *second=0, int *millisecond=0, int *microsecond=0) const
bsl::ostream & streamOut(bsl::ostream &stream) const
Definition bdlt_time.h:975
friend bool operator<=(const Time &, const Time &)
void setSecond(int second)
void setTime(int hour, int minute=0, int second=0, int millisecond=0, int microsecond=0)
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlt_time.h:858
int setTimeIfValid(int hour, int minute=0, int second=0, int millisecond=0, int microsecond=0)
Definition bdlt_time.h:839
int addInterval(const DatetimeInterval &interval)
void setMinute(int minute)
int addSeconds(int seconds)
Time & operator=(const Time &rhs)
Definition bdlt_time.h:756
int microsecond() const
Return the value of the microsecond attribute of this time object.
Definition bdlt_time.h:905
friend bool operator>=(const Time &, const Time &)
static int maxSupportedVersion()
Definition bdlt_time.h:969
int setMillisecondIfValid(int millisecond)
Definition bdlt_time.h:803
int addMinutes(int minutes)
int setMinuteIfValid(int minute)
Definition bdlt_time.h:815
static bool isValid(int hour, int minute=0, int second=0, int millisecond=0, int microsecond=0)
Definition bdlt_time.h:697
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
int second() const
Return the value of the second attribute of this time object.
Definition bdlt_time.h:928
void setMillisecond(int millisecond)
Time & operator+=(const DatetimeInterval &rhs)
Definition bdlt_time.h:765
int validateAndSetTime(int hour, int minute=0, int second=0, int millisecond=0)
Definition bdlt_time.h:981
Time()
Create a Time object having the value 24:00:00.000000.
Definition bdlt_time.h:730
void setHour(int hour)
int addMicroseconds(bsls::Types::Int64 microseconds)
friend void hashAppend(HASHALG &hashAlg, const Time &)
int addTime(int hours, int minutes=0, int seconds=0, int milliseconds=0, bsls::Types::Int64 microseconds=0)
int printToBuffer(char *result, int numBytes, int fractionalSecondPrecision=6) const
int millisecond() const
Return the value of the millisecond attribute of this time object.
Definition bdlt_time.h:912
int addMilliseconds(int milliseconds)
int setSecondIfValid(int second)
Definition bdlt_time.h:827
Time & operator-=(const DatetimeInterval &rhs)
Definition bdlt_time.h:772
void setMicrosecond(int microsecond)
~Time()=default
Destroy this 'Time' object.
friend bool operator<(const Time &, const Time &)
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlt_time.h:938
int minute() const
Return the value of the minute attribute of this time object.
Definition bdlt_time.h:920
int setHourIfValid(int hour)
Definition bdlt_time.h:779
friend bool operator==(const Time &, const Time &)
friend bool operator>(const Time &, const Time &)
int addHours(int hours)
int hour() const
Return the value of the hour attribute of this time object.
Definition bdlt_time.h:898
friend DatetimeInterval operator-(const Time &, const Time &)
Definition bsls_atomic.h:892
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PERFORMANCEHINT_UNLIKELY_HINT
Definition bsls_performancehint.h:484
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
#define BSLS_REVIEW(X)
Definition bsls_review.h:949
void hashAppend(HASH_ALGORITHM &hashAlg, const baljsn::EncoderTestAddress &object)
Definition baljsn_encoder_testtypes.h:9236
Definition bbldc_basicisma30360.h:112
bool operator>(const Date &lhs, const Date &rhs)
bool operator<(const Date &lhs, const Date &rhs)
bool operator==(const Calendar &lhs, const Calendar &rhs)
Date operator-(const Date &date, int numDays)
bool operator>=(const Date &lhs, const Date &rhs)
Date operator+(const Date &date, int numDays)
bsl::ostream & operator<<(bsl::ostream &stream, const Calendar &calendar)
bool operator<=(const Date &lhs, const Date &rhs)
void hashAppend(HASHALG &hashAlg, const Calendar &object)
bool operator!=(const Calendar &lhs, const Calendar &rhs)
Definition bdlbb_blob.h:576
Definition bdlt_timeunitratio.h:199
static const bsls::Types::Int64 k_S_PER_M
Definition bdlt_timeunitratio.h:285
static const int k_S_PER_M_32
Definition bdlt_timeunitratio.h:339
static const int k_H_PER_D_32
Definition bdlt_timeunitratio.h:346
static const int k_US_PER_MS_32
Definition bdlt_timeunitratio.h:330
static const int k_MS_PER_D_32
Definition bdlt_timeunitratio.h:337
static const bsls::Types::Int64 k_MS_PER_S
Definition bdlt_timeunitratio.h:280
static const bsls::Types::Int64 k_US_PER_H
Definition bdlt_timeunitratio.h:277
static const int k_M_PER_H_32
Definition bdlt_timeunitratio.h:343
static const bsls::Types::Int64 k_M_PER_H
Definition bdlt_timeunitratio.h:289
static const bsls::Types::Int64 k_US_PER_MS
Definition bdlt_timeunitratio.h:273
static const int k_MS_PER_S_32
Definition bdlt_timeunitratio.h:334
static const bsls::Types::Int64 k_US_PER_D
Definition bdlt_timeunitratio.h:278
static const bsls::Types::Int64 k_US_PER_S
Definition bdlt_timeunitratio.h:275
static const bsls::Types::Int64 k_US_PER_M
Definition bdlt_timeunitratio.h:276
long long Int64
Definition bsls_types.h:132