BDE 4.39.x Production Release
Loading...
Searching...
No Matches
baltzo_zoneinfo.h
Go to the documentation of this file.
1/// @file baltzo_zoneinfo.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// baltzo_zoneinfo.h -*-C++-*-
8#ifndef INCLUDED_BALTZO_ZONEINFO
9#define INCLUDED_BALTZO_ZONEINFO
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup baltzo_zoneinfo baltzo_zoneinfo
15/// @brief Provide a value type to represent a time zone.
16/// @addtogroup bal
17/// @{
18/// @addtogroup baltzo
19/// @{
20/// @addtogroup baltzo_zoneinfo
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#baltzo_zoneinfo-purpose"> Purpose</a>
25/// * <a href="#baltzo_zoneinfo-classes"> Classes </a>
26/// * <a href="#baltzo_zoneinfo-description"> Description </a>
27/// * <a href="#baltzo_zoneinfo-baltzo-zoneinfotransition"> baltzo::ZoneinfoTransition </a>
28/// * <a href="#baltzo_zoneinfo-baltzo-zoneinfo"> baltzo::Zoneinfo </a>
29/// * <a href="#baltzo_zoneinfo-zoneinfo-database"> Zoneinfo Database </a>
30/// * <a href="#baltzo_zoneinfo-posixextendedrangedescription"> posixExtendedRangeDescription </a>
31/// * <a href="#baltzo_zoneinfo-usage"> Usage </a>
32/// * <a href="#baltzo_zoneinfo-example-1-populate-a-baltzo-zoneinfo"> Example 1: Populate a baltzo::Zoneinfo </a>
33/// * <a href="#baltzo_zoneinfo-example-2-converting-utc-to-local-time"> Example 2: Converting UTC to Local Time </a>
34///
35/// # Purpose {#baltzo_zoneinfo-purpose}
36/// Provide a value type to represent a time zone.
37///
38/// # Classes {#baltzo_zoneinfo-classes}
39///
40/// - baltzo::Zoneinfo: information about a time zone
41/// - baltzo::ZoneinfoTransition: attributes representing a time transition
42///
43/// @see baltzo_localtimedescriptor, baltzo_zoneinfoutil
44///
45/// # Description {#baltzo_zoneinfo-description}
46/// This component provides a *value* *semantic* type,
47/// `baltzo::Zoneinfo`, that represents the information about a specific time
48/// zone contained in the Zoneinfo database. In addition, this component
49/// provides an unconstrained *in-core* *value-semantic* type
50/// `baltzo::ZoneinfoTransition` that can be used to characterize a transition
51/// for time zones.
52///
53/// ## baltzo::ZoneinfoTransition {#baltzo_zoneinfo-baltzo-zoneinfotransition}
54///
55///
56/// A `baltzo::ZoneinfoTransition` contains:
57/// @code
58/// Name Type
59/// ---------- --------------------------
60/// utcTime bdlt::EpochUtil::TimeT64
61/// descriptor baltzo::LocalTimeDescriptor
62/// @endcode
63/// * `utcTime`: UTC time when a transition occurs
64/// * `descriptor`: local time value corresponding to the time transition
65///
66/// For example, in New York on March 14, 2011, at the instant 1 a.m., clocks
67/// are set forward by an hour to mark the transition from Eastern Standard Time
68/// to Eastern Daylight Time. This change can be represented by a
69/// `baltzo::ZoneinfoTransition` object whose `utcTime` refers to March 14,
70/// 2011, 1am and whose `descriptor` describes Eastern Daylight Time (i.e.,
71/// description is "EDT", `dstInEffectFlag` is `true`, and `utcOffsetInSeconds`
72/// is -14,400 (-4 * 60 * 60)).
73///
74/// ## baltzo::Zoneinfo {#baltzo_zoneinfo-baltzo-zoneinfo}
75///
76///
77/// A `baltzo::Zoneinfo` contains:
78///
79/// * the time zone identifier (e.g., "America/New_York" or "Asia/Tokyo")
80/// * the ordered sequence of `baltzo::ZoneinfoTransition` objects,
81/// representing the various transitions from UTC for this time zone.
82/// * an optional POSIX-like TZ environment string used to represent
83/// far-reaching times past the end of the explicit time zone data.
84///
85/// A `baltzo::Zoneinfo` object also provides the method
86/// `findTransitionForUtcTime` that allows a client to find, in the sequence of
87/// transitions, the appropriate transition whose local-time descriptor
88/// describes the properties of local time, at a specified UTC time, for the
89/// time zone in question. Note that, even though this information is
90/// sufficient for converting local date and time, to their corresponding values
91/// in other time zones, clients are encouraged to use the utilities provided in
92/// @ref baltzo_timezoneutil . Also note that, `baltzo::Zoneinfo` objects are
93/// typically populated by the client through the `baltzo::Loader` protocol, and
94/// not directly.
95///
96/// ## Zoneinfo Database {#baltzo_zoneinfo-zoneinfo-database}
97///
98///
99/// This database, also referred to as either the TZ database or the Olson
100/// database (after its creator, Arthur Olson), is a standard, public-domain
101/// time-zone information distribution used by many software systems (including
102/// a number of Unix variants and the Java Runtime Environment). Information
103/// about the Zoneinfo database -- including the time zone rules for the
104/// supported time zones, and source code for the `zic` compiler (for compiling
105/// those rules into the binary representation used by this component) -- can be
106/// found online at `http://www.iana.org/time-zones/repository/tz-link.html`.
107/// This time zone information can be used to perform the conversion of dates
108/// and times from UTC to their corresponding dates and times in a given time
109/// zone and vice-versa. (See @ref baltzo_zoneinfobinaryreader for more
110/// information about the binary file format.)
111///
112/// ## posixExtendedRangeDescription {#baltzo_zoneinfo-posixextendedrangedescription}
113///
114///
115/// This string may be populated with a POSIX-like TZ string that describes
116/// rules for local time are handled before the first and after the last
117/// local-time transitions maintained by this object. Typically this is used
118/// for computing local time values far in the future. The rules for the
119/// encoded string can be found online at
120/// `http://www.ibm.com/developerworks/aix/library/au-aix-posix/`.
121///
122/// ## Usage {#baltzo_zoneinfo-usage}
123///
124///
125/// The following usage examples illustrate how to populate a `baltzo::Zoneinfo`
126/// object and use it to transform a UTC time into a local time.
127///
128/// ### Example 1: Populate a baltzo::Zoneinfo {#baltzo_zoneinfo-example-1-populate-a-baltzo-zoneinfo}
129///
130///
131/// Suppose we want to represent the time-zone information for New York, in 2010
132/// using a `baltzo::Zoneinfo` object. In order to do so, we need to provide
133/// the UTC date-times (transitions) after which the time zone changes its
134/// offset from UTC, or daylight-saving Time starts or ends.
135///
136/// First, we define two times "Mar 14, 2010 6:00 AM" and "Nov 07, 2010 7:00 AM"
137/// representing respectively the UTC time at which New York transitions to
138/// Eastern Daylight-saving Time (EDT) and Eastern Standard Time (EST) in 2010:
139/// @code
140/// bdlt::Datetime edtDatetime(2010, 03, 14, 2, 0);
141/// bdlt::Datetime estDatetime(2010, 11, 07, 2, 0);
142/// @endcode
143/// Then, we create two local-time descriptors that hold the offset from UTC and
144/// DST status for EST and EDT in New York in 2010, in terms of their
145/// `offsetFromUtcInSeconds`, `dstInEffectFlag` and `description` attributes:
146/// @code
147/// const baltzo::LocalTimeDescriptor est(-5 * 60 * 60, false, "EST");
148/// const baltzo::LocalTimeDescriptor edt(-4 * 60 * 60, true, "EDT");
149/// @endcode
150/// Note that these descriptors will be associated with the created transition
151/// times, to reflect how local time in New York changes its offset from UTC and
152/// DST status after specific times.
153///
154/// Next, we create an empty `baltzo::Zoneinfo` object that will be populated
155/// with the information necessary to describe the time zone for New York:
156/// @code
157/// baltzo::Zoneinfo newYorkTimeZone;
158/// @endcode
159/// Then, before being able to associate the transition times with their
160/// corresponding descriptors, we need translate the transition times to
161/// `bdlt::EpochUtil::TimeT64`:
162/// @code
163/// bdlt::EpochUtil::TimeT64 edtTransitionTime =
164/// bdlt::EpochUtil::convertToTimeT64(edtDatetime);
165/// bdlt::EpochUtil::TimeT64 estTransitionTime =
166/// bdlt::EpochUtil::convertToTimeT64(estDatetime);
167/// @endcode
168/// Now, we associate the created descriptors with the transitions we indicated
169/// previously and add them to `newYorkTimeZone` using the `addTransition`
170/// method:
171/// @code
172/// newYorkTimeZone.addTransition(edtTransitionTime, edt);
173/// newYorkTimeZone.addTransition(estTransitionTime, est);
174/// @endcode
175/// Note that this insertion operation maintains the transitions in order of
176/// transition time, and therefore inserting transitions out-of-order, while not
177/// illegal, is very inefficient.
178///
179/// Finally we verify that the `newYorkTimeZone` contains the transitions we
180/// indicated:
181/// @code
182/// {
183/// baltzo::Zoneinfo::TransitionConstIterator it =
184/// newYorkTimeZone.beginTransitions();
185///
186/// assert(it->utcTime() == edtTransitionTime);
187/// assert(it->descriptor() == edt);
188/// ++it;
189/// assert(it->utcTime() == estTransitionTime);
190/// assert(it->descriptor() == est);
191/// }
192/// @endcode
193/// Notice that the iterator refers to a `baltzo::ZoneinfoTransition` object.
194///
195/// ### Example 2: Converting UTC to Local Time {#baltzo_zoneinfo-example-2-converting-utc-to-local-time}
196///
197///
198/// Suppose that we want to program a function, `utcToLocalTime` to perform the
199/// conversion from a UTC time value to the corresponding local time value, in a
200/// given time zone, and return the computed local time:
201///
202/// First we declare the function `utcToLocalTime` and its contract:
203/// @code
204/// /// Return the `bdlt::DatetimeTz` value representing the date, time and
205/// /// offset from UTC (rounded to the minute) value of the local time,
206/// /// corresponding to the specified `utcTime` in the specified
207/// /// `timeZone`. The behavior is undefined if the `utcTime` precedes the
208/// /// time of the first transition contained in `timeZone` and
209/// /// `0 < timeZone.numTransitions()`.
210/// static bdlt::DatetimeTz utcToLocalTime(const bdlt::Datetime& utcTime,
211/// const baltzo::Zoneinfo& timeZone)
212/// {
213/// @endcode
214/// Then, we check the precondition of `utcToLocalTime`, by checking that
215/// `timeZone` contains at least one transitions and comparing `utcTime` to the
216/// first transition time in `timeZone`:
217/// @code
218/// BSLS_ASSERT(0 < timeZone.numTransitions());
219/// BSLS_ASSERT(timeZone.firstTransition().utcTime() <=
220/// bdlt::EpochUtil::convertToTimeT64(utcTime));
221/// @endcode
222/// Next, we obtain the appropriate `baltzo::ZoneinfoTransition` object,
223/// invoking the method `findTransitionForUtcTime` on `timeZone`:
224/// @code
225/// baltzo::Zoneinfo::TransitionConstIterator it =
226/// timeZone.findTransitionForUtcTime(utcTime);
227/// @endcode
228/// Then, we access the descriptor associated with the transition to which `it`
229/// refers, and calculate the offset from UTC rounded to the minute:
230/// @code
231/// const baltzo::ZoneinfoTransition& transition = *it;
232/// const int offsetInMinutes =
233/// transition.descriptor().utcOffsetInSeconds() / 60;
234/// @endcode
235/// Now, we apply the obtained `offsetInMinutes` to the originally specified
236/// `utcTime` obtaining the corresponding local time in the specified
237/// `timeZone`:
238/// @code
239/// bdlt::Datetime temp(utcTime);
240/// temp.addMinutes(offsetInMinutes);
241/// @endcode
242/// Finally, return the local time value together with its offset from UTC:
243/// @code
244/// return bdlt::DatetimeTz(temp, offsetInMinutes);
245/// }
246/// @endcode
247/// Suppose, now, we want to convert UTC time to the corresponding local time in
248/// New York. We can do so using the previously defined function
249/// `utcToLocalTime` and reusing the `baltzo::Zoneinfo` object,
250/// `newYorkTimeZone` of Example 1.
251///
252/// First, we define `bdlt::Datetime` object representing the UTC time "Apr 10,
253/// 2010 12:00":
254/// @code
255/// bdlt::Datetime utcDatetime(2010, 04, 10, 12, 0, 0);
256/// @endcode
257/// Then, we invoke `utcToLocalTime` passing `newYorkTimeZone` as a time zone
258/// and save the result:
259/// @code
260/// bdlt::DatetimeTz nyDatetime = utcToLocalTime(utcDatetime, newYorkTimeZone);
261/// @endcode
262/// Finally, we compute the New York local time corresponding to `utcDatetime`,
263/// verify that "April 10, 2010 8:00" is the computed time:
264/// @code
265/// const bdlt::Datetime expectedTime(2010, 4, 10, 8, 0, 0);
266/// assert(-4 * 60 == nyDatetime.offset());
267/// assert(expectedTime == nyDatetime.localDatetime());
268/// @endcode
269/// @}
270/** @} */
271/** @} */
272
273/** @addtogroup bal
274 * @{
275 */
276/** @addtogroup baltzo
277 * @{
278 */
279/** @addtogroup baltzo_zoneinfo
280 * @{
281 */
282
283#include <balscm_version.h>
284
286
287#include <bdlt_datetime.h>
288#include <bdlt_epochutil.h>
289
290#include <bslalg_swaputil.h>
291
292#include <bslma_allocator.h>
293#include <bslma_bslallocator.h>
295
297#include <bslmf_movableref.h>
299
300#include <bsls_assert.h>
301#include <bsls_keyword.h>
302#include <bsls_review.h>
303#include <bsls_types.h>
304
305#include <bsl_cstring.h>
306#include <bsl_iosfwd.h>
307#include <bsl_set.h>
308#include <bsl_string.h>
309#include <bsl_vector.h>
310
311
312namespace baltzo {
313
314 // ========================
315 // class ZoneinfoTransition
316 // ========================
317
318/// This class is an unconstrained *in-core* value-semantic class that
319/// characterizes a transition when the local time value of a time-zone
320/// changes. The salient attributes of this type are the `utcTime`
321/// (representing seconds from UTC), and `descriptor` representing the local
322/// time value after the transition.
323///
324/// See @ref baltzo_zoneinfo
326
327 // DATA
328 bdlt::EpochUtil::TimeT64 d_utcTime; // UTC time (representing in
329 // seconds from epoch) when the
330 // time transition occurs
331
332 const LocalTimeDescriptor *d_descriptor_p; // pointer to the descriptor
333 // associated with this
334 // transition (held, not owned)
335
336 // FRIENDS
337 friend class Zoneinfo;
338
339 // PRIVATE CREATORS
340
341 /// Create a `ZoneinfoTransition` object having the specified `utcTime`
342 /// and, `descriptor` attribute values.
343 ///
344 /// \pre The behavior is undefined unless `descriptor` remains valid for the lifetime of this object.
347
348 public:
349 // TRAITS
352
353 // CREATORS
354
355 /// Destroy this object.
357
358 // ACCESSORS
359
360 /// Return a reference providing non-modifiable access to the
361 /// `descriptor` attribute of this object.
362 const LocalTimeDescriptor& descriptor() const;
363
364 /// Return the value of the `utcTime` attribute of this object.
366
367 // Aspects
368
369 /// Write the value of this object to the specified output `stream` in a
370 /// human-readable format, and return a reference to `stream`.
371 /// Optionally specify an initial indentation `level`, whose absolute
372 /// value is incremented recursively for nested objects. If `level` is
373 /// specified, optionally specify `spacesPerLevel`, whose absolute value
374 /// indicates the number of spaces per indentation level for this and
375 /// all of its nested objects. If `level` is negative, suppress
376 /// indentation of the first line. If `spacesPerLevel` is negative,
377 /// format the entire output on one line, suppressing all but the
378 /// initial indentation (as governed by `level`). If `stream` is not valid on entry, this operation has no effect.
379 ///
380 /// \note Note that the format
381 /// is not fully specified, and can change without notice.
382 bsl::ostream& print(bsl::ostream& stream,
383 int level = 0,
384 int spacesPerLevel = 4) const;
385};
386
387// FREE OPERATORS
388
389/// Return `true` if the specified `lhs` and `rhs` objects have the same
390/// value, and `false` otherwise. Two `ZoneinfoTransition` objects have the
391/// same value if the corresponding value of their `utcTime` attribute is
392/// the same and both refer to the same `descriptor` address.
393bool operator==(const ZoneinfoTransition& lhs, const ZoneinfoTransition& rhs);
394
395/// Return `true` if the specified `lhs` and `rhs` objects do not have the
396/// same value, and `false` otherwise. Two `ZoneinfoTransition` objects do
397/// not have the same value if the corresponding value of their `utcTime` is
398/// not the same or if they do not refer to the same `descriptor` address.
399bool operator!=(const ZoneinfoTransition& lhs, const ZoneinfoTransition& rhs);
400
401/// Return `true` if the value of the specified `lhs` is less than (ordered before) the value of the specified `rhs`.
402///
403/// \note Note that the value of `lhs`
404/// is less than the value of `rhs` if the value of the `utcTime` attribute
405/// of `lhs` is less than the value of the `utcTime` attribute of `rhs`.
406bool operator<(const ZoneinfoTransition& lhs, const ZoneinfoTransition& rhs);
407
408/// Write the value of the specified `object` to the specified output
409/// `stream` in a single-line format, and return a reference to `stream`.
410/// If `stream` is not valid on entry, this operation has no effect.
411///
412/// \note Note that this human-readable format is not fully specified and can change
413/// without notice. Also note that this method has the same behavior as
414/// `object.print(stream, 0, -1)` with the attribute names elided.
415bsl::ostream& operator<<(bsl::ostream& stream,
416 const ZoneinfoTransition& object);
417
418 // ==============
419 // class Zoneinfo
420 // ==============
421
422/// This class is a value-semantic type holding a structured representation
423/// of the information contained in an Zoneinfo (or "Olson") time zone
424/// database for a *single* locale (e.g., "America/New_York"). The salient
425/// attributes of this type are the string identifier and the ordered
426/// sequence of `ZoneinfoTransition` objects.
427///
428/// See @ref baltzo_zoneinfo
429class Zoneinfo {
430
431 // PRIVATE TYPES
432
433 /// This `class` is a private functor that provides a comparator
434 /// predicate for the type `LocalTimeDescriptor`, so that it can be
435 /// stored in associative containers such as `bsl::set`.
436 ///
437 /// See @ref baltzo_zoneinfo
438 class DescriptorLess {
439
440 public:
441 /// Return `true` if the value of the specified `lhs` is less than
442 /// (ordered before) the value of the specified `rhs`.
443 ///
444 /// \note Note that the value of `lhs` is less than the value of `rhs` if the value
445 /// of the corresponding `utcOffsetInSeconds`, `description`, and
446 /// `dstInEffectFlag` attributes of `lhs` when incrementally
447 /// compared one at a time in that order is less than the attribute
448 /// value of `rhs`. Also note that the comparison moves to the next
449 /// attribute only when the corresponding attribute values compare
450 /// equal.
451 bool operator()(const LocalTimeDescriptor& lhs,
452 const LocalTimeDescriptor& rhs) const;
453 };
454
455 /// Alias for the sequence of transitions that characterize a `Zoneinfo`
456 /// object.
458
459 /// Alias for the set of unique local-time descriptors that are managed
460 /// by a `Zoneinfo` object.
462
463 // DATA
464 bsl::string d_identifier;
465 // this time zone's id
466
467 DescriptorSet d_descriptors;
468 // set of local time descriptors for this time zone
469 // (e.g., 'EST')
470
471 TransitionSequence d_transitions;
472 // transitions, from one local time descriptor to
473 // another (e.g., 'EST' to 'EDT'), ordered by the
474 // time the transition occurred (or will occur)
475
476 bsl::string d_posixExtendedRangeDescription;
477 // optional POSIX-like TZ environment string
478 // representing far-reaching times
479
480 // FRIENDS
481 friend bool operator==(const Zoneinfo&, const Zoneinfo&);
482
483 public:
484 // TYPES
486
487 /// Alias for a bi-directional `const` iterator over the sequence of
488 /// transitions maintained by a `Zoneinfo` object.
490
491 // TRAITS
493
494 // CREATORS
495
496 /// Create a `Zoneinfo` object having the values:
497 /// @code
498 /// numTransitions() == 0
499 /// identifier() == ""
500 /// @endcode
501 /// Optionally specify an `allocator` (e.g., the address of a
502 /// `bslma::Allocator` object) to supply memory; otherwise, the default
503 /// allocator is used.
504 Zoneinfo();
505 explicit Zoneinfo(const allocator_type& allocator);
506
507 /// Create a `Zoneinfo` object having the same value as the specified
508 /// `original` object. Optionally specify an `allocator` (e.g., the
509 /// address of a `bslma::Allocator` object) to supply memory; otherwise,
510 /// the default allocator is used.
511 Zoneinfo(const Zoneinfo& original,
513
514 /// Create a `Zoneinfo` object having the same value and the same
515 /// allocator as the specified `original` object. The value of
516 /// `original` becomes unspecified but valid, and its allocator remains
517 /// unchanged.
519
520 /// Create a `Zoneinfo` object having the same value as the specified
521 /// `original` object, using the specified `allocator` (e.g., the
522 /// address of a `bslma::Allocator` object) to supply memory. The
523 /// allocator of `original` remains unchanged. If `original` and the
524 /// newly created object have the same allocator then the value of
525 /// `original` becomes unspecified but valid, and no exceptions will be
526 /// thrown; otherwise `original` is unchanged and an exception may be
527 /// thrown.
530
531 // MANIPULATORS
532
533 /// Assign to this object the value of the specified `rhs` object, and
534 /// return a reference providing modifiable access to this object.
535 Zoneinfo& operator=(const Zoneinfo& rhs);
536
537 /// Assign to this object the value of the specified `rhs` object, and
538 /// return a non-`const` reference to this object. The allocators of
539 /// this object and `rhs` both remain unchanged. If `rhs` and this
540 /// object have the same allocator then the value of `rhs` becomes
541 /// unspecified but valid, and no exceptions will be thrown; otherwise
542 /// `rhs` is unchanged (and an exception may be thrown).
544
545 /// Add to this object a transition occurring at the specified `utcTime`
546 /// when the local time in the described time-zone adopts the
547 /// characteristics of the specified `descriptor`. If a transition at
548 /// `utcTime` is already present, replace it's local-time descriptor
549 /// with `descriptor`.
551 const LocalTimeDescriptor& descriptor);
552
553 /// Set the `identifier` attribute of this object to the specified
554 /// `value`.
555 void setIdentifier(const bsl::string_view& value);
556 void setIdentifier(const char *value);
557
558 /// Set the `posixExtendedRangeDescription` attribute of this object,
559 /// used to describe local time transitions far in the future, to the
560 /// specified `value` (see {posixExtendedRangeDescription}).
562 void setPosixExtendedRangeDescription(const char *value);
563
564 /// Efficiently exchange the value of this object with the value of the
565 /// specified `other` object. This method provides the no-throw exception-safety guarantee.
566 ///
567 /// \pre The behavior is undefined unless this
568 /// object was created with the same allocator as `other`.
569 void swap(Zoneinfo& other);
570
571 // ACCESSORS
572
573 /// Return the allocator used by this object to supply memory.
574 ///
575 /// \note Note that if no allocator was supplied at construction the currently
576 /// installed default allocator is used.
577 ///
578 /// @deprecated Use @ref get_allocator() instead.
580
581 /// Return an iterator providing non-modifiable access to the transition
582 /// that holds the local-time descriptor associated with the specified `utcTime`.
583 ///
584 /// \pre The behavior is undefined unless `numTransitions() > 0`
585 /// and `utcTime` is at or after the transition returned by
586 /// `firstTransition`.
588 const bdlt::Datetime& utcTime) const;
589
590 /// Return a reference providing non-modifiable access to the first
591 /// transition contained in this object.
592 ///
593 /// \pre The behavior is undefined unless `numTransitions() > 0`.
594 const ZoneinfoTransition& firstTransition() const;
595
596 /// Return the allocator used by this object to supply memory.
597 ///
598 /// \note Note that if no allocator was supplied at construction the default
599 /// allocator in effect at construction is used.
601
602 /// Return a reference providing non-modifiable access to the
603 /// `identifier` attribute of this object.
604 const bsl::string& identifier() const;
605
606 /// Return a reference providing non-modifiable access to the
607 /// `posixExtendedRangeDescription` attribute of this object, used to
608 /// describe local time transitions far in the future (see
609 /// {posixExtendedRangeDescription}).
611
612 /// Return the number of transitions maintained by this zone info.
613 bsl::size_t numTransitions() const;
614
615 /// Return an iterator providing non-modifiable access to the first
616 /// transition in the ordered sequence of transitions maintained by this object.
617 ///
618 /// \note Note that if `beginTransitions() == endTransitions()` then
619 /// there are no transitions stored by this object.
621
622 /// Return an iterator providing non-modifiable access to the one-past
623 /// the last transition in the ordered sequence of transitions that is associated with this object.
624 ///
625 /// \note Note that if
626 /// `beginTransitions() == endTransitions()` then there are no
627 /// transitions stored by this object.
629
630 /// Write the value of this object to the specified output `stream` in a
631 /// human-readable format, and return a reference to `stream`.
632 /// Optionally specify an initial indentation `level`, whose absolute
633 /// value is incremented recursively for nested objects. If `level` is
634 /// specified, optionally specify `spacesPerLevel`, whose absolute value
635 /// indicates the number of spaces per indentation level for this and
636 /// all of its nested objects. If `level` is negative, suppress
637 /// indentation of the first line. If `spacesPerLevel` is negative,
638 /// format the entire output on one line, suppressing all but the
639 /// initial indentation (as governed by `level`). If `stream` is not valid on entry, this operation has no effect.
640 ///
641 /// \note Note that the format
642 /// is not fully specified, and can change without notice.
643 bsl::ostream& print(bsl::ostream& stream,
644 int level = 0,
645 int spacesPerLevel = 4) const;
646};
647
648// FREE OPERATORS
649
650/// Return `true` if the specified `lhs` and `rhs` objects have the same
651/// value, and `false` otherwise. Two `Zoneinfo` objects have the same
652/// value if the corresponding value of their `identifier` attribute is the
653/// same and if both store the same sequence of transitions, ordered by
654/// time.
655bool operator==(const Zoneinfo& lhs, const Zoneinfo& rhs);
656
657/// Return `true` if the specified `lhs` and `rhs` objects do not have the
658/// same value, and `false` otherwise. Two `Zoneinfo` objects do not have
659/// the same value if their corresponding `identifier` attribute does not
660/// have the same value, or if both do *not* store the same sequence of
661/// transitions, ordered by time.
662bool operator!=(const Zoneinfo& lhs, const Zoneinfo& rhs);
663
664/// Write the value of the specified `object` to the specified output
665/// `stream` in a single-line format, and return a reference to `stream`.
666/// If `stream` is not valid on entry, this operation has no effect.
667///
668/// \note Note that this human-readable format is not fully specified, can change
669/// without notice, and is logically equivalent to:
670/// @code
671/// print(stream, 0, -1);
672/// @endcode
673bsl::ostream& operator<<(bsl::ostream& stream, const Zoneinfo& object);
674
675// FREE FUNCTIONS
676
677/// Exchange the values of the specified `a` and `b` objects. This function
678/// provides the no-throw exception-safety guarantee if the two objects were
679/// created with the same allocator and the basic guarantee otherwise.
680void swap(Zoneinfo& a, Zoneinfo& b);
681
682// ============================================================================
683// INLINE DEFINITIONS
684// ============================================================================
685
686 // ------------------------
687 // class ZoneinfoTransition
688 // ------------------------
689
690// PRIVATE CREATORS
691inline
692ZoneinfoTransition::ZoneinfoTransition(bdlt::EpochUtil::TimeT64 utcTime,
693 const LocalTimeDescriptor *descriptor)
694: d_utcTime(utcTime)
695, d_descriptor_p(descriptor)
696{
697 BSLS_ASSERT(descriptor);
698}
699
700// CREATORS
701inline
702ZoneinfoTransition::~ZoneinfoTransition()
703{
704 BSLS_ASSERT(d_descriptor_p);
705}
706
707// ACCESSORS
708inline
709const LocalTimeDescriptor& ZoneinfoTransition::descriptor() const
710{
711 return *d_descriptor_p;
712}
713
714inline
715bdlt::EpochUtil::TimeT64 ZoneinfoTransition::utcTime() const
716{
717 return d_utcTime;
718}
719
720} // close package namespace
721
722// FREE OPERATORS
723inline
724bool baltzo::operator==(const ZoneinfoTransition& lhs,
725 const ZoneinfoTransition& rhs)
726{
727 return lhs.utcTime() == rhs.utcTime()
728 && lhs.descriptor() == rhs.descriptor();
729}
730
731inline
732bool baltzo::operator!=(const ZoneinfoTransition& lhs,
733 const ZoneinfoTransition& rhs)
734{
735 return !(lhs == rhs);
736}
737
738inline
739bool baltzo::operator<(const ZoneinfoTransition& lhs,
740 const ZoneinfoTransition& rhs)
741{
742 return lhs.utcTime() < rhs.utcTime();
743}
744
745namespace baltzo {
746
747 // --------------
748 // class Zoneinfo
749 // --------------
750
751// CREATORS
752inline
754: d_identifier()
755, d_descriptors()
756, d_transitions()
757, d_posixExtendedRangeDescription()
758{
759}
760
761inline
763: d_identifier(allocator)
764, d_descriptors(allocator)
765, d_transitions(allocator)
766, d_posixExtendedRangeDescription(allocator)
767{
768}
769
770// MANIPULATORS
771inline
773{
774 Zoneinfo(rhs, get_allocator()).swap(*this);
775 return *this;
776}
777
778inline
780{
781 BSLS_ASSERT(0 != value.data());
782
783 d_identifier = value;
784}
785
786inline
787void Zoneinfo::setIdentifier(const char *value)
788{
789 BSLS_ASSERT(value);
790
791 d_identifier = value;
792}
793
794inline
796{
797 BSLS_ASSERT(0 != value.data());
798
799 d_posixExtendedRangeDescription.assign(value.begin(), value.end());
800}
801
802inline
804{
805 BSLS_ASSERT(value);
806
807 d_posixExtendedRangeDescription = value;
808}
809
810inline
812{
814
815 bslalg::SwapUtil::swap(&d_identifier, &other.d_identifier);
816 bslalg::SwapUtil::swap(&d_descriptors, &other.d_descriptors);
817 bslalg::SwapUtil::swap(&d_transitions, &other.d_transitions);
818 bslalg::SwapUtil::swap(&d_posixExtendedRangeDescription,
819 &other.d_posixExtendedRangeDescription);
820}
821
822// ACCESSORS
823inline
828
829inline
831{
833
834 return d_transitions.front();
835}
836
837inline
839{
840 return d_identifier.get_allocator();
841}
842
843inline
845{
846 return d_identifier;
847}
848
849inline
851{
852 return d_posixExtendedRangeDescription;
853}
854
855inline
856bsl::size_t Zoneinfo::numTransitions() const
857{
858 return d_transitions.size();
859}
860
861inline
863{
864 return d_transitions.begin();
865}
866
867inline
869{
870 return d_transitions.end();
871}
872
873} // close package namespace
874
875// FREE OPERATORS
876inline
877bool baltzo::operator==(const Zoneinfo& lhs, const Zoneinfo& rhs)
878{
879 return lhs.identifier() == rhs.identifier()
880 && lhs.posixExtendedRangeDescription() ==
881 rhs.posixExtendedRangeDescription()
882 && lhs.numTransitions() == rhs.numTransitions()
883 && bsl::equal(lhs.d_transitions.begin(),
884 lhs.d_transitions.end(),
885 rhs.d_transitions.begin());
886}
887
888inline
889bool baltzo::operator!=(const Zoneinfo& lhs, const Zoneinfo& rhs)
890{
891 return !(lhs == rhs);
892}
893
894
895
896#endif
897
898// ----------------------------------------------------------------------------
899// Copyright 2020 Bloomberg Finance L.P.
900//
901// Licensed under the Apache License, Version 2.0 (the "License");
902// you may not use this file except in compliance with the License.
903// You may obtain a copy of the License at
904//
905// http://www.apache.org/licenses/LICENSE-2.0
906//
907// Unless required by applicable law or agreed to in writing, software
908// distributed under the License is distributed on an "AS IS" BASIS,
909// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
910// See the License for the specific language governing permissions and
911// limitations under the License.
912// ----------------------------- END-OF-FILE ----------------------------------
913
914/** @} */
915/** @} */
916/** @} */
Definition baltzo_localtimedescriptor.h:186
Definition baltzo_zoneinfo.h:325
~ZoneinfoTransition()
Destroy this object.
Definition baltzo_zoneinfo.h:702
bdlt::EpochUtil::TimeT64 utcTime() const
Return the value of the utcTime attribute of this object.
Definition baltzo_zoneinfo.h:715
BSLMF_NESTED_TRAIT_DECLARATION(ZoneinfoTransition, bslmf::IsBitwiseMoveable)
const LocalTimeDescriptor & descriptor() const
Definition baltzo_zoneinfo.h:709
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Definition baltzo_zoneinfo.h:429
bslma::Allocator * allocator() const
Definition baltzo_zoneinfo.h:824
allocator_type get_allocator() const
Definition baltzo_zoneinfo.h:838
TransitionConstIterator findTransitionForUtcTime(const bdlt::Datetime &utcTime) const
friend bool operator==(const Zoneinfo &, const Zoneinfo &)
bsl::ostream & print(bsl::ostream &stream, int level=0, int spacesPerLevel=4) const
Zoneinfo(bslmf::MovableRef< Zoneinfo > original) BSLS_KEYWORD_NOEXCEPT
TransitionConstIterator endTransitions() const
Definition baltzo_zoneinfo.h:868
const bsl::string & posixExtendedRangeDescription() const
Definition baltzo_zoneinfo.h:850
Zoneinfo & operator=(bslmf::MovableRef< Zoneinfo > rhs)
void addTransition(bdlt::EpochUtil::TimeT64 utcTime, const LocalTimeDescriptor &descriptor)
TransitionConstIterator beginTransitions() const
Definition baltzo_zoneinfo.h:862
TransitionSequence::const_iterator TransitionConstIterator
Definition baltzo_zoneinfo.h:489
void setPosixExtendedRangeDescription(const bsl::string_view &value)
Definition baltzo_zoneinfo.h:795
Zoneinfo(const Zoneinfo &original, const allocator_type &allocator=allocator_type())
const bsl::string & identifier() const
Definition baltzo_zoneinfo.h:844
void setIdentifier(const bsl::string_view &value)
Definition baltzo_zoneinfo.h:779
void swap(Zoneinfo &other)
Definition baltzo_zoneinfo.h:811
bsl::allocator< char > allocator_type
Definition baltzo_zoneinfo.h:485
bsl::size_t numTransitions() const
Return the number of transitions maintained by this zone info.
Definition baltzo_zoneinfo.h:856
BSLMF_NESTED_TRAIT_DECLARATION(Zoneinfo, bslma::UsesBslmaAllocator)
Zoneinfo & operator=(const Zoneinfo &rhs)
Definition baltzo_zoneinfo.h:772
Zoneinfo()
Definition baltzo_zoneinfo.h:753
const ZoneinfoTransition & firstTransition() const
Definition baltzo_zoneinfo.h:830
Zoneinfo(bslmf::MovableRef< Zoneinfo > original, const allocator_type &allocator)
Definition bdlt_datetime.h:330
Definition bslma_bslallocator.h:588
BloombergLP::bslma::Allocator * mechanism() const
Definition bslma_bslallocator.h:1146
Definition bslstl_stringview.h:471
BSLS_KEYWORD_CONSTEXPR const_iterator end() const BSLS_KEYWORD_NOEXCEPT
Return the past-the-end iterator for this view.
Definition bslstl_stringview.h:1848
BSLS_KEYWORD_CONSTEXPR const_pointer data() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringview.h:1988
BSLS_KEYWORD_CONSTEXPR const_iterator begin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringview.h:1830
Definition bslstl_string.h:1252
basic_string & assign(const basic_string &replacement)
Definition bslstl_string.h:6347
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this string to supply memory.
Definition bslstl_string.h:7423
Definition bslstl_set.h:691
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:3019
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2866
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2874
reference front()
Definition bslstl_vector.h:2922
Definition bslstl_vector.h:1120
ZoneinfoTransition const * const_iterator
Definition bslstl_vector.h:1153
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:182
Definition bslma_allocator.h:545
Definition bslmf_movableref.h:752
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
Definition baltzo_datafileloader.h:259
bool operator==(const LocalDatetime &lhs, const LocalDatetime &rhs)
bool operator<(const ZoneinfoTransition &lhs, const ZoneinfoTransition &rhs)
bool operator!=(const LocalDatetime &lhs, const LocalDatetime &rhs)
bsl::ostream & operator<<(bsl::ostream &stream, DstPolicy::Enum value)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
ALLOCATOR & lhs
Definition bslstl_string.h:3917
bsls::Types::Int64 TimeT64
Definition bdlt_epochutil.h:210
Definition bslma_usesbslmaallocator.h:344
Definition bslmf_isbitwisemoveable.h:718