BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlt_datetz.h
Go to the documentation of this file.
1/// @file bdlt_datetz.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlt_datetz.h -*-C++-*-
8#ifndef INCLUDED_BDLT_DATETZ
9#define INCLUDED_BDLT_DATETZ
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlt_datetz bdlt_datetz
15/// @brief Provide a representation of a date with time zone offset.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlt
19/// @{
20/// @addtogroup bdlt_datetz
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlt_datetz-purpose"> Purpose</a>
25/// * <a href="#bdlt_datetz-classes"> Classes </a>
26/// * <a href="#bdlt_datetz-description"> Description </a>
27/// * <a href="#bdlt_datetz-caveats-on-time-zone-support"> Caveats on Time Zone Support </a>
28/// * <a href="#bdlt_datetz-iso-standard-text-representation"> ISO Standard Text Representation </a>
29/// * <a href="#bdlt_datetz-usage"> Usage </a>
30/// * <a href="#bdlt_datetz-example-1-representing-dates-in-different-time-zones"> Example 1: Representing Dates In Different Time Zones </a>
31///
32/// # Purpose {#bdlt_datetz-purpose}
33/// Provide a representation of a date with time zone offset.
34///
35/// # Classes {#bdlt_datetz-classes}
36///
37/// - bdlt::DateTz: local-date value with time zone offset from UTC
38///
39/// @see bdlt_date, bdlt_datetimetz, bdlt_datetzformatter, bdlt_formatdoc
40///
41/// # Description {#bdlt_datetz-description}
42/// This component provides a single value-semantic class,
43/// `bdlt::DateTz`, that represents a date value in a particular time zone.
44/// Each `bdlt::DateTz` object contains a time zone offset from UTC (in minutes)
45/// and a `bdlt::Date` value in that time zone. For logical consistency, the
46/// date value and offset should correspond to a geographically valid time zone,
47/// but such consistency is the user's responsibility. This component does not
48/// enforce logical constraints on any values.
49///
50/// ## Caveats on Time Zone Support {#bdlt_datetz-caveats-on-time-zone-support}
51///
52///
53/// A `bdlt::DateTz` value is intended to be interpreted as a value in a local
54/// time zone, along with the offset of that value from UTC. However, there are
55/// some problems with this simple interpretation. First of all, the offset
56/// value may not correspond to any time zone that has ever existed. For
57/// example, the offset value could be set to one minute, or to 1,234 minutes.
58/// The meaning of the resulting "local time" value is always clear, but the
59/// local time might not correspond to any geographical or historical time zone.
60///
61/// The second problem is more subtle. A given offset from UTC might be "valid"
62/// in that it corresponds to a real time zone, but the actual date value might
63/// not exist in that time zone. To make matters worse, a "valid" offset may
64/// not (indeed, rarely will) specify one time zone uniquely. Moreover, the
65/// date value might be valid in one time zone corresponding to a given offset,
66/// and not in another time zone.
67///
68/// For these reasons (and others), this component cannot and does not perform
69/// any validation relating to time zones or offsets. The user must take care
70/// to honor the "local date" contract of this component.
71///
72/// ## ISO Standard Text Representation {#bdlt_datetz-iso-standard-text-representation}
73///
74///
75/// A common standard text representation of a date and time value is described
76/// by ISO 8601. BDE provides the @ref bdlt_iso8601util component for conversion
77/// to and from the standard ISO8601 format.
78///
79/// ## Usage {#bdlt_datetz-usage}
80///
81///
82/// This section illustrates intended use of this component.
83///
84/// ### Example 1: Representing Dates In Different Time Zones {#bdlt_datetz-example-1-representing-dates-in-different-time-zones}
85///
86///
87/// Suppose that we need to compare dates in different time zones. The
88/// `bdlt::DateTz` type helps us to accomplish this by providing the
89/// `utcStartTime` method, which returns a `bdlt::Datetime` value corresponding
90/// to the UTC "point in time" when the local date starts (i.e. 000 hours local
91/// time).
92///
93/// First, we default construct an object `dateTz1`, which has an offset of 0,
94/// implying that the object represents a date in the UTC time zone.
95/// @code
96/// bdlt::DateTz dateTz1;
97/// assert(0 == dateTz1.offset());
98/// assert(dateTz1.localDate() == dateTz1.utcStartTime().date());
99/// assert(dateTz1.localDate() == bdlt::Date());
100/// @endcode
101/// Notice the value of a default contructed `bdlt::DateTz` object is the same
102/// as that of a default constructed `bdlt::Date` object.
103///
104/// Then, we construct two objects `dateTz2` and `dateTz3` to have a local date
105/// of 2013/12/31 in the EST time zone (UTC-5) and the pacific time zone (UTC-8)
106/// respectively:
107/// @code
108/// bdlt::DateTz dateTz2 (bdlt::Date(2013, 12, 31), -5 * 60);
109/// bdlt::DateTz dateTz3 (bdlt::Date(2013, 12, 31), -8 * 60);
110/// @endcode
111/// Next, we compare the local dates of the two `DateTz` objects, and verify
112/// that they compare equal:
113/// @code
114/// bdlt::Date localDate(2013, 12, 31);
115/// assert(localDate == dateTz2.localDate());
116/// assert(localDate == dateTz3.localDate());
117/// @endcode
118/// Now, we compare the starting time of the two `DateTz` objects using the
119/// `utcStartTime` method:
120/// @code
121/// assert(dateTz2.utcStartTime() < dateTz3.utcStartTime());
122/// @endcode
123/// @}
124/** @} */
125/** @} */
126
127/** @addtogroup bdl
128 * @{
129 */
130/** @addtogroup bdlt
131 * @{
132 */
133/** @addtogroup bdlt_datetz
134 * @{
135 */
136
137#include <bdlscm_version.h>
138
139#include <bdlt_date.h>
140#include <bdlt_datetime.h>
141
144
145#include <bsls_assert.h>
146#include <bsls_review.h>
147
148#include <bsl_iosfwd.h>
149
150
151namespace bdlt {
152
153 // ============
154 // class DateTz
155 // ============
156
157/// This value-semantic class describes a date value in a particular time
158/// zone, which is indicated using an offset from UTC (in minutes).
159///
160/// See @ref bdlt_datetz
161class DateTz {
162 // PRIVATE TYPES
163
164 /// This enumeration specifies the minimum and maximum time zone offset
165 /// values.
166 enum ValidOffsetRange {
167 k_MAX_OFFSET = 1440,
168 k_MIN_OFFSET = -1440
169 };
170
171 // DATA
172 Date d_localDate; // date value in timezone specified by `d_offset`
173 int d_offset; // offset from UTC (in minutes)
174
175 public:
176 // CLASS METHODS
177
178 /// Return `true` if the specified `localDate` and the specified time
179 /// zone `offset` represent a valid `DateTz` value, and `false`
180 /// otherwise. A `localDate` and `offset` represent a valid `DateTz` value if `offset` is in the range `( -1440 .. 1440 )`.
181 ///
182 /// \note Note that a
183 /// `true` result from this function does not guarantee that `offset`
184 /// corresponds to any geographical or historical time zone. Also note
185 /// that a `true` result from this function does not guarantee that
186 /// `localDate` itself is a valid `Date` object.
187 static bool isValid(const Date& localDate, int offset);
188
189 // Aspects
190
191 /// Return the maximum valid BDEX format version, as indicated by the
192 /// specified `versionSelector`, to be passed to the `bdexStreamOut` method.
193 ///
194 /// \note Note that it is highly recommended that `versionSelector`
195 /// be formatted as "YYYYMMDD", a date representation. Also note that
196 /// `versionSelector` should be a *compile*-time-chosen value that
197 /// selects a format version supported by both externalizer and
198 /// unexternalizer. See the `bslx` package-level documentation for more
199 /// information on BDEX streaming of value-semantic types and
200 /// containers.
201 static int maxSupportedBdexVersion(int versionSelector);
202
203 // CREATORS
204
205 /// Create a `DateTz` object having the (default) attribute values.
206 DateTz();
207
208 /// Create a `DateTz` object having a local date value equal to the
209 /// specified `localDate` and a time zone offset value from UTC equal to
210 /// the specified `offset` (in minutes).
211 ///
212 /// \pre The behavior is undefined unless `offset` is in the range `( -1440 .. 1440 )`.
213 /// \note Note that this
214 /// method provides no validation, and it is the user's responsibility
215 /// to ensure that `offset` represents a valid time zone and that
216 /// `localDate` represents a valid date in that time zone.
217 DateTz(const Date& localDate, int offset);
218
219 /// Create a `DateTz` object having the same value as the specified
220 /// `original` object.
221 DateTz(const DateTz& original);
222
223 // The following destructor is generated by the compiler, except in "SAFE"
224 // build modes (e.g., to enable the checking of class invariants).
225
226 /// Destroy this object.
227 ~DateTz();
228
229 // MANIPULATORS
230
231 /// Assign to this object the value of the specified `rhs` object, and
232 /// return a reference providing modifiable access to this object.
233 DateTz& operator=(const DateTz& rhs);
234
235 /// Set the local date and the time zone offset of this object to the
236 /// specified `localDate` and `offset` values respectively.
237 ///
238 /// \pre The behavior is undefined unless `offset` is in the range `( -1440 .. 1440 )`.
239 ///
240 /// \note Note that this method provides no validation,
241 /// and it is the user's responsibility to assure the consistency of the
242 /// resulting value.
243 void setDateTz(const Date& localDate, int offset);
244
245 /// Set the local date and time zone offset of this object to the
246 /// specified `localDate` and `offset` values respectively if
247 /// `localDate` and `offset` represent a valid `DateTz` value. Return 0
248 /// on success, and a non-zero value with no effect on this `DateTz`
249 /// object otherwise.
250 int setDateTzIfValid(const Date& localDate, int offset);
251
252 // Aspects
253
254 /// Assign to this object the value read from the specified input
255 /// `stream` using the specified `version` format, and return a
256 /// reference to `stream`. If `stream` is initially invalid, this
257 /// operation has no effect. If `version` is not supported, this object
258 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
259 /// If `version` is supported but `stream` becomes invalid during this
260 /// operation, this object has an undefined, but valid, state.
261 ///
262 /// \note Note that no version is read from `stream`. See the `bslx` package-level
263 /// documentation for more information on BDEX streaming of
264 /// value-semantic types and containers.
265 template <class STREAM>
266 STREAM& bdexStreamIn(STREAM& stream, int version);
267
268 // ACCESSORS
269
270 /// Return a `Date` object having the value of the local date represented by this object.
271 ///
272 /// \note Note that this is the `Date` supplied
273 /// at construction and may not correspond to the actual time zone
274 /// offset of the local system.
275 Date localDate() const;
276
277 /// Return the time zone offset of this `DateTz` object.
278 /// \note Note that the
279 /// offset is in minutes from UTC.
280 int offset() const;
281
282 /// Return a `Datetime` object having the value of the UTC "point in
283 /// time" when the local date starts (i.e., 0000 hours local time).
284 ///
285 /// \pre The behavior is undefined unless the local date starting time represents a valid `Datetime` value for the UTC timezone.
286 ///
287 /// \note Note that the
288 /// returned value is equal to:
289 /// @code
290 /// Datetime(localDate()).addMinutes(-offset());
291 /// @endcode
292 Datetime utcStartTime() const;
293
294 // Aspects
295
296 /// Write the value of this object, using the specified `version`
297 /// format, to the specified output `stream`, and return a reference to
298 /// `stream`. If `stream` is initially invalid, this operation has no
299 /// effect. If `version` is not supported, `stream` is invalidated, but otherwise unmodified.
300 ///
301 /// \note Note that `version` is not written to
302 /// `stream`. See the `bslx` package-level documentation for more
303 /// information on BDEX streaming of value-semantic types and
304 /// containers.
305 template <class STREAM>
306 STREAM& bdexStreamOut(STREAM& stream, int version) const;
307
308 /// Write the value of this object to the specified output `stream` in a
309 /// human-readable format, and return a reference to `stream`.
310 /// Optionally specify an initial indentation `level`, whose absolute
311 /// value is incremented recursively for nested objects. If `level` is
312 /// specified, optionally specify `spacesPerLevel`, whose absolute value
313 /// indicates the number of spaces per indentation level for this and
314 /// all of its nested objects. If `level` is negative, suppress
315 /// indentation of the first line. If `spacesPerLevel` is negative,
316 /// format the entire output on one line, suppressing all but the
317 /// initial indentation (as governed by `level`). If `stream` is not valid on entry, this operation has no effect.
318 ///
319 /// \note Note that the format
320 /// is not fully specified, and can change without notice.
321 bsl::ostream& print(bsl::ostream& stream,
322 int level = 0,
323 int spacesPerLevel = 4) const;
324
325#ifndef BDE_OPENSOURCE_PUBLICATION // pending deprecation
326
327 /// Return a `Datetime` object having the value of the UTC "point in
328 /// time" when the local date starts (i.e., 0000 hours local time).
329 ///
330 /// \pre The behavior is undefined unless the local date starting time represents a valid `Datetime` value for the UTC timezone.
331 ///
332 /// \note Note that the
333 /// returned value is equal to:
334 /// @code
335 /// Datetime(localDate()).addMinutes(-offset());
336 /// @endcode
337 ///
338 /// @deprecated replaced by `utcStartTime`.
339 Datetime gmtStartTime() const;
340
341 /// Return the most current BDEX streaming version number supported by
342 /// this class.
343 ///
344 /// @deprecated Use @ref maxSupportedBdexVersion(int) instead.
345 static int maxSupportedBdexVersion();
346
347 /// Set the local date and time zone offset of this object to the
348 /// specified `localDate` and `offset` values respectively if
349 /// `localDate` and `offset` represent a valid `DateTz` value. Return 0
350 /// on success, and a non-zero value with no effect on this `DateTz`
351 /// object otherwise.
352 ///
353 /// @deprecated Use @ref setDateTzIfValid instead.
354 int validateAndSetDateTz(const Date& localDate, int offset);
355
356#endif // BDE_OPENSOURCE_PUBLICATION -- pending deprecation
357
358};
359
360// FREE OPERATORS
361
362/// Return `true` if the specified `lhs` and `rhs` `DateTz` objects have the
363/// same value, and `false` otherwise. Two `DateTz` objects have the same
364/// value if they have the same local date value and the same time zone
365/// offset value.
366bool operator==(const DateTz& lhs, const DateTz& rhs);
367
368/// Return `true` if the specified `lhs` and `rhs` `DateTz` objects do not
369/// have the same value, and `false` otherwise. Two `DateTz` objects do not
370/// have the same value if they do not have the same local date values or
371/// the same time zone offset values.
372bool operator!=(const DateTz& lhs, const DateTz& rhs);
373
374/// Write the value of the specified `rhs` object to the specified output
375/// `stream` in a single-line format, and return a reference providing
376/// modifiable access to `stream`. If `stream` is not valid on entry, this operation has no effect.
377///
378/// \note Note that this human-readable format is not
379/// fully specified and can change without notice. Also note that this
380/// method has the same behavior as `object.print(stream, 0, -1)`, but with
381/// the attribute names elided.
382bsl::ostream& operator<<(bsl::ostream& stream, const DateTz& rhs);
383
384// FREE FUNCTIONS
385
386/// Pass the specified `object` to the specified `hashAlg`. This function
387/// integrates with the `bslh` modular hashing system and effectively provides a `bsl::hash` specialization for `DateTz`.
388///
389/// \note Note that two
390/// objects which represent the same UTC time but have different offsets
391/// will not (necessarily) hash to the same value.
392template <class HASHALG>
393void hashAppend(HASHALG& hashAlg, const DateTz& object);
394
395// ============================================================================
396// INLINE DEFINITIONS
397// ============================================================================
398
399 // ------------
400 // class DateTz
401 // ------------
402
403// CLASS METHODS
404inline
405bool DateTz::isValid(const Date&, int offset)
406{
407 return k_MIN_OFFSET < offset
408 && k_MAX_OFFSET > offset;
409}
410
411inline
412int DateTz::maxSupportedBdexVersion(int /* versionSelector */)
413{
414 return 1;
415}
416
417// CREATORS
418inline
420: d_localDate()
421, d_offset(0)
422{
423}
424
425inline
426DateTz::DateTz(const Date& localDate, int offset)
427: d_localDate(localDate)
428, d_offset(offset)
429{
431}
432
433inline
434DateTz::DateTz(const DateTz& original)
435: d_localDate(original.d_localDate)
436, d_offset(original.d_offset)
437{
438}
439
440inline
442{
443 BSLS_REVIEW(isValid(d_localDate, d_offset));
444}
445
446// MANIPULATORS
447inline
449{
450 d_localDate = rhs.d_localDate;
451 d_offset = rhs.d_offset;
452
453 return *this;
454}
455
456inline
457void DateTz::setDateTz(const Date& localDate, int offset)
458{
460
461 d_localDate = localDate;
462 d_offset = offset;
463}
464
465inline
466int DateTz::setDateTzIfValid(const Date& localDate, int offset)
467{
468 if (isValid(localDate, offset)) {
470 return 0; // RETURN
471 }
472 return -1;
473}
474
475 // Aspects
476
477template <class STREAM>
478STREAM& DateTz::bdexStreamIn(STREAM& stream, int version)
479{
480 if (stream) {
481 switch (version) { // switch on the schema version
482 case 1: {
484 localDate.bdexStreamIn(stream, 1);
485
486 int offset = 0;
487 stream.getInt32(offset);
488
489 if (stream && isValid(localDate, offset)) {
490 d_localDate = localDate;
491 d_offset = offset;
492 }
493 else {
494 stream.invalidate();
495 }
496 } break;
497 default: {
498 stream.invalidate(); // unrecognized version number
499 }
500 }
501 }
502 return stream;
503}
504
505// ACCESSORS
506inline
508{
509 return d_localDate;
510}
511
512inline
513int DateTz::offset() const
514{
515 return d_offset;
516}
517
518inline
520{
521 Datetime utc(d_localDate, Time(0,0,0,0));
522 utc.addMinutes(-d_offset);
523 return utc;
524}
525
526 // Aspects
527
528template <class STREAM>
529STREAM& DateTz::bdexStreamOut(STREAM& stream, int version) const
530{
531 if (stream) {
532 switch (version) { // switch on the schema version
533 case 1: {
534 d_localDate.bdexStreamOut(stream, 1);
535 stream.putInt32(d_offset);
536 } break;
537 default: {
538 stream.invalidate(); // unrecognized version number
539 }
540 }
541 }
542 return stream;
543}
544
545#ifndef BDE_OPENSOURCE_PUBLICATION // pending deprecation
546// DEPRECATED
547inline
549{
550 return utcStartTime();
551}
552
553inline
558
559inline
560int DateTz::validateAndSetDateTz(const Date& localDate, int offset)
561{
562 if (isValid(localDate, offset)) {
564 return 0; // RETURN
565 }
566 return -1;
567}
568
569#endif // BDE_OPENSOURCE_PUBLICATION -- pending deprecation
570
571} // close package namespace
572
573// FREE OPERATORS
574inline
575bool bdlt::operator==(const DateTz& lhs, const DateTz& rhs)
576{
577 return lhs.offset() == rhs.offset()
578 && lhs.localDate() == rhs.localDate();
579}
580
581inline
582bool bdlt::operator!=(const DateTz& lhs, const DateTz& rhs)
583{
584 return lhs.offset() != rhs.offset()
585 || lhs.localDate() != rhs.localDate();
586}
587
588inline
589bsl::ostream& bdlt::operator<<(bsl::ostream& stream, const DateTz& rhs)
590{
591 return rhs.print(stream, 0, -1);
592}
593
594// FREE FUNCTIONS
595template <class HASHALG>
596inline
597void bdlt::hashAppend(HASHALG& hashAlg, const DateTz& object)
598{
599 using ::BloombergLP::bslh::hashAppend;
600 hashAppend(hashAlg, object.localDate());
601 hashAppend(hashAlg, object.offset());
602}
603
604namespace bslmf {
605
606// TRAITS
607
608/// This template specialization for `IsBitwiseCopyable` indicates that
609/// `bdlt::DateTz` is a bitwise copyable type.
610template <>
611struct IsBitwiseCopyable<BloombergLP::bdlt::DateTz> : bsl::true_type {
612};
613
614} // close namespace bslmf
615
616
617#endif
618
619// ----------------------------------------------------------------------------
620// Copyright 2014 Bloomberg Finance L.P.
621//
622// Licensed under the Apache License, Version 2.0 (the "License");
623// you may not use this file except in compliance with the License.
624// You may obtain a copy of the License at
625//
626// http://www.apache.org/licenses/LICENSE-2.0
627//
628// Unless required by applicable law or agreed to in writing, software
629// distributed under the License is distributed on an "AS IS" BASIS,
630// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
631// See the License for the specific language governing permissions and
632// limitations under the License.
633// ----------------------------- END-OF-FILE ----------------------------------
634
635/** @} */
636/** @} */
637/** @} */
Definition bdlt_datetz.h:161
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlt_datetz.h:478
static bool isValid(const Date &localDate, int offset)
Definition bdlt_datetz.h:405
int validateAndSetDateTz(const Date &localDate, int offset)
Definition bdlt_datetz.h:560
int offset() const
Definition bdlt_datetz.h:513
int setDateTzIfValid(const Date &localDate, int offset)
Definition bdlt_datetz.h:466
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlt_datetz.h:529
DateTz()
Create a DateTz object having the (default) attribute values.
Definition bdlt_datetz.h:419
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
DateTz & operator=(const DateTz &rhs)
Definition bdlt_datetz.h:448
Date localDate() const
Definition bdlt_datetz.h:507
Datetime gmtStartTime() const
Definition bdlt_datetz.h:548
void setDateTz(const Date &localDate, int offset)
Definition bdlt_datetz.h:457
~DateTz()
Destroy this object.
Definition bdlt_datetz.h:441
static int maxSupportedBdexVersion()
Definition bdlt_datetz.h:554
Datetime utcStartTime() const
Definition bdlt_datetz.h:519
Definition bdlt_date.h:294
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlt_date.h:1013
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlt_date.h:924
Definition bdlt_datetime.h:330
Datetime & addMinutes(bsls::Types::Int64 minutes)
Definition bdlt_datetime.h:2062
Definition bdlt_time.h:195
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#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 Calendar &lhs, const Calendar &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, const Calendar &calendar)
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