BDE 4.14.0 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
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#include <bdlt_time.h>
142
145
146#include <bsls_assert.h>
147#include <bsls_review.h>
148
149#include <bsl_iosfwd.h>
150
151
152namespace bdlt {
153
154 // ============
155 // class DateTz
156 // ============
157
158/// This value-semantic class describes a date value in a particular time
159/// zone, which is indicated using an offset from UTC (in minutes).
160///
161/// See @ref bdlt_datetz
162class DateTz {
163
164 // PRIVATE TYPES
165
166 /// This enumeration specifies the minimum and maximum time zone offset
167 /// values.
168 enum ValidOffsetRange {
169 k_MAX_OFFSET = 1440,
170 k_MIN_OFFSET = -1440
171 };
172
173 // DATA
174 Date d_localDate; // date value in timezone specified by 'd_offset'
175 int d_offset; // offset from UTC (in minutes)
176
177 public:
178 // CLASS METHODS
179
180 /// Return `true` if the specified `localDate` and the specified time
181 /// zone `offset` represent a valid `DateTz` value, and `false`
182 /// otherwise. A `localDate` and `offset` represent a valid `DateTz`
183 /// value if `offset` is in the range `( -1440 .. 1440 )`. Note that a
184 /// `true` result from this function does not guarantee that `offset`
185 /// corresponds to any geographical or historical time zone. Also note
186 /// that a `true` result from this function does not guarantee that
187 /// `localDate` itself is a valid `Date` object.
188 static bool isValid(const Date& localDate, int offset);
189
190 // Aspects
191
192 /// Return the maximum valid BDEX format version, as indicated by the
193 /// specified `versionSelector`, to be passed to the `bdexStreamOut`
194 /// method. 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). The behavior is undefined
211 /// unless `offset` is in the range `( -1440 .. 1440 )`. Note that this
212 /// method provides no validation, and it is the user's responsibility
213 /// to ensure that `offset` represents a valid time zone and that
214 /// `localDate` represents a valid date in that time zone.
215 DateTz(const Date& localDate, int offset);
216
217 /// Create a `DateTz` object having the same value as the specified
218 /// `original` object.
219 DateTz(const DateTz& original);
220
221 // The following destructor is generated by the compiler, except in "SAFE"
222 // build modes (e.g., to enable the checking of class invariants).
223
224 /// Destroy this object.
225 ~DateTz();
226
227 // MANIPULATORS
228
229 /// Assign to this object the value of the specified `rhs` object, and
230 /// return a reference providing modifiable access to this object.
231 DateTz& operator=(const DateTz& rhs);
232
233 /// Set the local date and the time zone offset of this object to the
234 /// specified `localDate` and `offset` values respectively. The
235 /// behavior is undefined unless `offset` is in the range
236 /// `( -1440 .. 1440 )`. Note that this method provides no validation,
237 /// and it is the user's responsibility to assure the consistency of the
238 /// resulting value.
239 void setDateTz(const Date& localDate, int offset);
240
241 /// Set the local date and time zone offset of this object to the
242 /// specified `localDate` and `offset` values respectively if
243 /// `localDate` and `offset` represent a valid `DateTz` value. Return 0
244 /// on success, and a non-zero value with no effect on this `DateTz`
245 /// object otherwise.
246 int setDateTzIfValid(const Date& localDate, int offset);
247
248 // Aspects
249
250 /// Assign to this object the value read from the specified input
251 /// `stream` using the specified `version` format, and return a
252 /// reference to `stream`. If `stream` is initially invalid, this
253 /// operation has no effect. If `version` is not supported, this object
254 /// is unaltered and `stream` is invalidated, but otherwise unmodified.
255 /// If `version` is supported but `stream` becomes invalid during this
256 /// operation, this object has an undefined, but valid, state. Note
257 /// that no version is read from `stream`. See the `bslx` package-level
258 /// documentation for more information on BDEX streaming of
259 /// value-semantic types and containers.
260 template <class STREAM>
261 STREAM& bdexStreamIn(STREAM& stream, int version);
262
263 // ACCESSORS
264
265 /// Return a `Date` object having the value of the local date
266 /// represented by this object. Note that this is the `Date` supplied
267 /// at construction and may not correspond to the actual time zone
268 /// offset of the local system.
269 Date localDate() const;
270
271 /// Return the time zone offset of this `DateTz` object. Note that the
272 /// offset is in minutes from UTC.
273 int offset() const;
274
275 /// Return a `Datetime` object having the value of the UTC "point in
276 /// time" when the local date starts (i.e., 0000 hours local time). The
277 /// behavior is undefined unless the local date starting time represents
278 /// a valid `Datetime` value for the UTC timezone. Note that the
279 /// returned value is equal to:
280 /// @code
281 /// Datetime(localDate()).addMinutes(-offset());
282 /// @endcode
283 Datetime utcStartTime() const;
284
285 // Aspects
286
287 /// Write the value of this object, using the specified `version`
288 /// format, to the specified output `stream`, and return a reference to
289 /// `stream`. If `stream` is initially invalid, this operation has no
290 /// effect. If `version` is not supported, `stream` is invalidated, but
291 /// otherwise unmodified. Note that `version` is not written to
292 /// `stream`. See the `bslx` package-level documentation for more
293 /// information on BDEX streaming of value-semantic types and
294 /// containers.
295 template <class STREAM>
296 STREAM& bdexStreamOut(STREAM& stream, int version) const;
297
298 /// Write the value of this object to the specified output `stream` in a
299 /// human-readable format, and return a reference to `stream`.
300 /// Optionally specify an initial indentation `level`, whose absolute
301 /// value is incremented recursively for nested objects. If `level` is
302 /// specified, optionally specify `spacesPerLevel`, whose absolute value
303 /// indicates the number of spaces per indentation level for this and
304 /// all of its nested objects. If `level` is negative, suppress
305 /// indentation of the first line. If `spacesPerLevel` is negative,
306 /// format the entire output on one line, suppressing all but the
307 /// initial indentation (as governed by `level`). If `stream` is not
308 /// valid on entry, this operation has no effect. Note that the format
309 /// is not fully specified, and can change without notice.
310 bsl::ostream& print(bsl::ostream& stream,
311 int level = 0,
312 int spacesPerLevel = 4) const;
313
314#ifndef BDE_OPENSOURCE_PUBLICATION // pending deprecation
315
316 /// @deprecated replaced by `utcStartTime`.
317 ///
318 /// Return a `Datetime` object having the value of the UTC "point in
319 /// time" when the local date starts (i.e., 0000 hours local time). The
320 /// behavior is undefined unless the local date starting time represents
321 /// a valid `Datetime` value for the UTC timezone. Note that the
322 /// returned value is equal to:
323 /// @code
324 /// Datetime(localDate()).addMinutes(-offset());
325 /// @endcode
326 Datetime gmtStartTime() const;
327
328 /// @deprecated Use @ref maxSupportedBdexVersion(int) instead.
329 ///
330 /// Return the most current BDEX streaming version number supported by
331 /// this class.
332 static int maxSupportedBdexVersion();
333
334 /// Set the local date and time zone offset of this object to the
335 /// specified `localDate` and `offset` values respectively if
336 /// `localDate` and `offset` represent a valid `DateTz` value. Return 0
337 /// on success, and a non-zero value with no effect on this `DateTz`
338 /// object otherwise.
339 int validateAndSetDateTz(const Date& localDate, int offset);
340
341#endif // BDE_OPENSOURCE_PUBLICATION -- pending deprecation
342
343};
344
345// FREE OPERATORS
346
347/// Return `true` if the specified `lhs` and `rhs` `DateTz` objects have the
348/// same value, and `false` otherwise. Two `DateTz` objects have the same
349/// value if they have the same local date value and the same time zone
350/// offset value.
351bool operator==(const DateTz& lhs, const DateTz& rhs);
352
353/// Return `true` if the specified `lhs` and `rhs` `DateTz` objects do not
354/// have the same value, and `false` otherwise. Two `DateTz` objects do not
355/// have the same value if they do not have the same local date values or
356/// the same time zone offset values.
357bool operator!=(const DateTz& lhs, const DateTz& rhs);
358
359/// Write the value of the specified `rhs` object to the specified output
360/// `stream` in a single-line format, and return a reference providing
361/// modifiable access to `stream`. If `stream` is not valid on entry, this
362/// operation has no effect. Note that this human-readable format is not
363/// fully specified and can change without notice. Also note that this
364/// method has the same behavior as `object.print(stream, 0, -1)`, but with
365/// the attribute names elided.
366bsl::ostream& operator<<(bsl::ostream& stream, const DateTz& rhs);
367
368// FREE FUNCTIONS
369
370/// Pass the specified `object` to the specified `hashAlg`. This function
371/// integrates with the `bslh` modular hashing system and effectively
372/// provides a `bsl::hash` specialization for `DateTz`. Note that two
373/// objects which represent the same UTC time but have different offsets
374/// will not (necessarily) hash to the same value.
375template <class HASHALG>
376void hashAppend(HASHALG& hashAlg, const DateTz& object);
377
378// ============================================================================
379// INLINE DEFINITIONS
380// ============================================================================
381
382 // ------------
383 // class DateTz
384 // ------------
385
386// CLASS METHODS
387inline
388bool DateTz::isValid(const Date&, int offset)
389{
390 return k_MIN_OFFSET < offset
391 && k_MAX_OFFSET > offset;
392}
393
394 // Aspects
395
396inline
397int DateTz::maxSupportedBdexVersion(int /* versionSelector */)
398{
399 return 1;
400}
401
402// CREATORS
403inline
405: d_localDate()
406, d_offset(0)
407{
408}
409
410inline
411DateTz::DateTz(const Date& localDate, int offset)
412: d_localDate(localDate)
413, d_offset(offset)
414{
416}
417
418inline
419DateTz::DateTz(const DateTz& original)
420: d_localDate(original.d_localDate)
421, d_offset(original.d_offset)
422{
423}
424
425inline
427{
428 BSLS_REVIEW(isValid(d_localDate, d_offset));
429}
430
431// MANIPULATORS
432inline
434{
435 d_localDate = rhs.d_localDate;
436 d_offset = rhs.d_offset;
437
438 return *this;
439}
440
441inline
442void DateTz::setDateTz(const Date& localDate, int offset)
443{
445
446 d_localDate = localDate;
447 d_offset = offset;
448}
449
450inline
451int DateTz::setDateTzIfValid(const Date& localDate, int offset)
452{
453 if (isValid(localDate, offset)) {
455 return 0; // RETURN
456 }
457 return -1;
458}
459
460 // Aspects
461
462template <class STREAM>
463STREAM& DateTz::bdexStreamIn(STREAM& stream, int version)
464{
465 if (stream) {
466 switch (version) { // switch on the schema version
467 case 1: {
469 localDate.bdexStreamIn(stream, 1);
470
471 int offset;
472 stream.getInt32(offset);
473
474 if (stream && isValid(localDate, offset)) {
475 d_localDate = localDate;
476 d_offset = offset;
477 }
478 else {
479 stream.invalidate();
480 }
481 } break;
482 default: {
483 stream.invalidate(); // unrecognized version number
484 }
485 }
486 }
487 return stream;
488}
489
490// ACCESSORS
491inline
493{
494 return d_localDate;
495}
496
497inline
498int DateTz::offset() const
499{
500 return d_offset;
501}
502
503inline
505{
506 Datetime utc(d_localDate, Time(0,0,0,0));
507 utc.addMinutes(-d_offset);
508 return utc;
509}
510
511 // Aspects
512
513template <class STREAM>
514STREAM& DateTz::bdexStreamOut(STREAM& stream, int version) const
515{
516 if (stream) {
517 switch (version) { // switch on the schema version
518 case 1: {
519 d_localDate.bdexStreamOut(stream, 1);
520 stream.putInt32(d_offset);
521 } break;
522 default: {
523 stream.invalidate(); // unrecognized version number
524 }
525 }
526 }
527 return stream;
528}
529
530#ifndef BDE_OPENSOURCE_PUBLICATION // pending deprecation
531// DEPRECATED
532inline
534{
535 return utcStartTime();
536}
537
538inline
543
544inline
545int DateTz::validateAndSetDateTz(const Date& localDate, int offset)
546{
547 if (isValid(localDate, offset)) {
549 return 0; // RETURN
550 }
551 return -1;
552}
553
554#endif // BDE_OPENSOURCE_PUBLICATION -- pending deprecation
555
556} // close package namespace
557
558// FREE OPERATORS
559inline
560bool bdlt::operator==(const DateTz& lhs, const DateTz& rhs)
561{
562 return lhs.offset() == rhs.offset()
563 && lhs.localDate() == rhs.localDate();
564}
565
566inline
567bool bdlt::operator!=(const DateTz& lhs, const DateTz& rhs)
568{
569 return lhs.offset() != rhs.offset()
570 || lhs.localDate() != rhs.localDate();
571}
572
573inline
574bsl::ostream& bdlt::operator<<(bsl::ostream& stream, const DateTz& rhs)
575{
576 return rhs.print(stream, 0, -1);
577}
578
579// FREE FUNCTIONS
580template <class HASHALG>
581inline
582void bdlt::hashAppend(HASHALG& hashAlg, const DateTz& object)
583{
584 using ::BloombergLP::bslh::hashAppend;
585 hashAppend(hashAlg, object.localDate());
586 hashAppend(hashAlg, object.offset());
587}
588
589namespace bslmf {
590
591// TRAITS
592
593/// This template specialization for `IsBitwiseCopyable` indicates that
594/// `bdlt::DateTz` is a bitwise copyable type.
595template <>
596struct IsBitwiseCopyable<BloombergLP::bdlt::DateTz> : bsl::true_type {
597};
598
599} // close namespace bslmf
600
601
602
603#endif
604
605// ----------------------------------------------------------------------------
606// Copyright 2014 Bloomberg Finance L.P.
607//
608// Licensed under the Apache License, Version 2.0 (the "License");
609// you may not use this file except in compliance with the License.
610// You may obtain a copy of the License at
611//
612// http://www.apache.org/licenses/LICENSE-2.0
613//
614// Unless required by applicable law or agreed to in writing, software
615// distributed under the License is distributed on an "AS IS" BASIS,
616// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
617// See the License for the specific language governing permissions and
618// limitations under the License.
619// ----------------------------- END-OF-FILE ----------------------------------
620
621/** @} */
622/** @} */
623/** @} */
Definition bdlt_datetz.h:162
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlt_datetz.h:463
static bool isValid(const Date &localDate, int offset)
Definition bdlt_datetz.h:388
int validateAndSetDateTz(const Date &localDate, int offset)
Definition bdlt_datetz.h:545
int offset() const
Definition bdlt_datetz.h:498
int setDateTzIfValid(const Date &localDate, int offset)
Definition bdlt_datetz.h:451
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlt_datetz.h:514
DateTz()
Create a DateTz object having the (default) attribute values.
Definition bdlt_datetz.h:404
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
DateTz & operator=(const DateTz &rhs)
Definition bdlt_datetz.h:433
Date localDate() const
Definition bdlt_datetz.h:492
Datetime gmtStartTime() const
Definition bdlt_datetz.h:533
void setDateTz(const Date &localDate, int offset)
Definition bdlt_datetz.h:442
~DateTz()
Destroy this object.
Definition bdlt_datetz.h:426
static int maxSupportedBdexVersion()
Definition bdlt_datetz.h:539
Datetime utcStartTime() const
Definition bdlt_datetz.h:504
Definition bdlt_date.h:294
STREAM & bdexStreamOut(STREAM &stream, int version) const
Definition bdlt_date.h:985
STREAM & bdexStreamIn(STREAM &stream, int version)
Definition bdlt_date.h:896
Definition bdlt_datetime.h:331
Datetime & addMinutes(bsls::Types::Int64 minutes)
Definition bdlt_datetime.h:1992
Definition bdlt_time.h:196
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#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 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)
Definition bdlbb_blob.h:576