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