BDE 4.14.0 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#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
312#include <bsl_algorithm.h>
313#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
314
315
316namespace baltzo {
317
318 // ========================
319 // class ZoneinfoTransition
320 // ========================
321
322/// This class is an unconstrained *in-core* value-semantic class that
323/// characterizes a transition when the local time value of a time-zone
324/// changes. The salient attributes of this type are the `utcTime`
325/// (representing seconds from UTC), and `descriptor` representing the local
326/// time value after the transition.
327///
328/// See @ref baltzo_zoneinfo
330
331 // DATA
332 bdlt::EpochUtil::TimeT64 d_utcTime; // UTC time (representing in
333 // seconds from epoch) when the
334 // time transition occurs
335
336 const LocalTimeDescriptor *d_descriptor_p; // pointer to the descriptor
337 // associated with this
338 // transition (held, not owned)
339
340 // FRIENDS
341 friend class Zoneinfo;
342
343 // PRIVATE CREATORS
344
345 /// Create a `ZoneinfoTransition` object having the specified `utcTime`
346 /// and, `descriptor` attribute values. The behavior is undefined
347 /// unless `descriptor` remains valid for the lifetime of this object.
350
351 public:
352 // TRAITS
355
356 // CREATORS
357
358 /// Destroy this object.
360
361 // ACCESSORS
362
363 /// Return a reference providing non-modifiable access to the
364 /// `descriptor` attribute of this object.
365 const LocalTimeDescriptor& descriptor() const;
366
367 /// Return the value of the `utcTime` attribute of this object.
369
370 // Aspects
371
372 /// Write the value of this object to the specified output `stream` in a
373 /// human-readable format, and return a reference to `stream`.
374 /// Optionally specify an initial indentation `level`, whose absolute
375 /// value is incremented recursively for nested objects. If `level` is
376 /// specified, optionally specify `spacesPerLevel`, whose absolute value
377 /// indicates the number of spaces per indentation level for this and
378 /// all of its nested objects. If `level` is negative, suppress
379 /// indentation of the first line. If `spacesPerLevel` is negative,
380 /// format the entire output on one line, suppressing all but the
381 /// initial indentation (as governed by `level`). If `stream` is not
382 /// valid on entry, this operation has no effect. Note that the format
383 /// is not fully specified, and can change without notice.
384 bsl::ostream& print(bsl::ostream& stream,
385 int level = 0,
386 int spacesPerLevel = 4) const;
387};
388
389// FREE OPERATORS
390
391/// Return `true` if the specified `lhs` and `rhs` objects have the same
392/// value, and `false` otherwise. Two `ZoneinfoTransition` objects have the
393/// same value if the corresponding value of their `utcTime` attribute is
394/// the same and both refer to the same `descriptor` address.
395bool operator==(const ZoneinfoTransition& lhs, const ZoneinfoTransition& rhs);
396
397/// Return `true` if the specified `lhs` and `rhs` objects do not have the
398/// same value, and `false` otherwise. Two `ZoneinfoTransition` objects do
399/// not have the same value if the corresponding value of their `utcTime` is
400/// not the same or if they do not refer to the same `descriptor` address.
401bool operator!=(const ZoneinfoTransition& lhs, const ZoneinfoTransition& rhs);
402
403/// Return `true` if the value of the specified `lhs` is less than (ordered
404/// before) the value of the specified `rhs`. Note that the value of `lhs`
405/// is less than the value of `rhs` if the value of the `utcTime` attribute
406/// of `lhs` is less than the value of the `utcTime` attribute of `rhs`.
407bool operator<(const ZoneinfoTransition& lhs, const ZoneinfoTransition& rhs);
408
409/// Write the value of the specified `object` to the specified output
410/// `stream` in a single-line format, and return a reference to `stream`.
411/// If `stream` is not valid on entry, this operation has no effect. Note
412/// 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`. Note that
443 /// the value of `lhs` is less than the value of `rhs` if the value
444 /// of the corresponding `utcOffsetInSeconds`, `description`, and
445 /// `dstInEffectFlag` attributes of `lhs` when incrementally
446 /// compared one at a time in that order is less than the attribute
447 /// value of `rhs`. Also note that the comparison moves to the next
448 /// attribute only when the corresponding attribute values compare
449 /// equal.
450 bool operator()(const LocalTimeDescriptor& lhs,
451 const LocalTimeDescriptor& rhs) const;
452 };
453
454 /// Alias for the sequence of transitions that characterize a `Zoneinfo`
455 /// object.
457
458 /// Alias for the set of unique local-time descriptors that are managed
459 /// by a `Zoneinfo` object.
461
462 // DATA
463 bsl::string d_identifier;
464 // this time zone's id
465
466 DescriptorSet d_descriptors;
467 // set of local time descriptors for this time zone
468 // (e.g., 'EST')
469
470 TransitionSequence d_transitions;
471 // transitions, from one local time descriptor to
472 // another (e.g., 'EST' to 'EDT'), ordered by the
473 // time the transition occurred (or will occur)
474
475 bsl::string d_posixExtendedRangeDescription;
476 // optional POSIX-like TZ environment string
477 // representing far-reaching times
478
479 // FRIENDS
480 friend bool operator==(const Zoneinfo&, const Zoneinfo&);
481
482 public:
483 // TYPES
485
486 /// Alias for a bi-directional `const` iterator over the sequence of
487 /// transitions maintained by a `Zoneinfo` object.
489
490 // TRAITS
492
493 // CREATORS
494
495 Zoneinfo();
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 explicit Zoneinfo(const allocator_type& allocator);
505
506 /// Create a `Zoneinfo` object having the same value as the specified
507 /// `original` object. Optionally specify an `allocator` (e.g., the
508 /// address of a `bslma::Allocator` object) to supply memory; otherwise,
509 /// the default allocator is used.
510 Zoneinfo(const Zoneinfo& original,
512
513 /// Create a `Zoneinfo` object having the same value and the same
514 /// allocator as the specified `original` object. The value of
515 /// `original` becomes unspecified but valid, and its allocator remains
516 /// unchanged.
518
519 /// Create a `Zoneinfo` object having the same value as the specified
520 /// `original` object, using the specified `allocator` (e.g., the
521 /// address of a `bslma::Allocator` object) to supply memory. The
522 /// allocator of `original` remains unchanged. If `original` and the
523 /// newly created object have the same allocator then the value of
524 /// `original` becomes unspecified but valid, and no exceptions will be
525 /// thrown; otherwise `original` is unchanged and an exception may be
526 /// thrown.
529
530 // MANIPULATORS
531
532 /// Assign to this object the value of the specified `rhs` object, and
533 /// return a reference providing modifiable access to this object.
534 Zoneinfo& operator=(const Zoneinfo& rhs);
535
536 /// Assign to this object the value of the specified `rhs` object, and
537 /// return a non-`const` reference to this object. The allocators of
538 /// this object and `rhs` both remain unchanged. If `rhs` and this
539 /// object have the same allocator then the value of `rhs` becomes
540 /// unspecified but valid, and no exceptions will be thrown; otherwise
541 /// `rhs` is unchanged (and an exception may be thrown).
543
544 /// Add to this object a transition occurring at the specified `utcTime`
545 /// when the local time in the described time-zone adopts the
546 /// characteristics of the specified `descriptor`. If a transition at
547 /// `utcTime` is already present, replace it's local-time descriptor
548 /// with `descriptor`.
550 const LocalTimeDescriptor& descriptor);
551
552 void setIdentifier(const bsl::string_view& value);
553 /// Set the `identifier` attribute of this object to the specified
554 /// `value`.
555 void setIdentifier(const char *value);
556
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}).
561 void setPosixExtendedRangeDescription(const char *value);
562
563 /// Efficiently exchange the value of this object with the value of the
564 /// specified `other` object. This method provides the no-throw
565 /// exception-safety guarantee. The behavior is undefined unless this
566 /// object was created with the same allocator as `other`.
567 void swap(Zoneinfo& other);
568
569 // ACCESSORS
570
571 /// @deprecated Use @ref get_allocator() instead.
572 ///
573 /// Return the allocator used by this object to supply memory. Note
574 /// that if no allocator was supplied at construction the currently
575 /// installed default allocator is used.
577
578 /// Return an iterator providing non-modifiable access to the transition
579 /// that holds the local-time descriptor associated with the specified
580 /// `utcTime`. The behavior is undefined unless `numTransitions() > 0`
581 /// and `utcTime` is at or after the transition returned by
582 /// `firstTransition`.
584 const bdlt::Datetime& utcTime) const;
585
586 /// Return a reference providing non-modifiable access to the first
587 /// transition contained in this object. The behavior is undefined
588 /// unless `numTransitions() > 0`.
589 const ZoneinfoTransition& firstTransition() const;
590
591 /// Return the allocator used by this object to supply memory. Note
592 /// that if no allocator was supplied at construction the default
593 /// allocator in effect at construction is used.
595
596 /// Return a reference providing non-modifiable access to the
597 /// `identifier` attribute of this object.
598 const bsl::string& identifier() const;
599
600 /// Return a reference providing non-modifiable access to the
601 /// `posixExtendedRangeDescription` attribute of this object, used to
602 /// describe local time transitions far in the future (see
603 /// {posixExtendedRangeDescription}).
605
606 /// Return the number of transitions maintained by this zone info.
607 bsl::size_t numTransitions() const;
608
609 /// Return an iterator providing non-modifiable access to the first
610 /// transition in the ordered sequence of transitions maintained by this
611 /// object. Note that if `beginTransitions() == endTransitions()` then
612 /// there are no transitions stored by this object.
614
615 /// Return an iterator providing non-modifiable access to the one-past
616 /// the last transition in the ordered sequence of transitions that is
617 /// associated with this object. Note that if
618 /// `beginTransitions() == endTransitions()` then there are no
619 /// transitions stored by this object.
621
622 /// Write the value of this object to the specified output `stream` in a
623 /// human-readable format, and return a reference to `stream`.
624 /// Optionally specify an initial indentation `level`, whose absolute
625 /// value is incremented recursively for nested objects. If `level` is
626 /// specified, optionally specify `spacesPerLevel`, whose absolute value
627 /// indicates the number of spaces per indentation level for this and
628 /// all of its nested objects. If `level` is negative, suppress
629 /// indentation of the first line. If `spacesPerLevel` is negative,
630 /// format the entire output on one line, suppressing all but the
631 /// initial indentation (as governed by `level`). If `stream` is not
632 /// valid on entry, this operation has no effect. Note that the format
633 /// is not fully specified, and can change without notice.
634 bsl::ostream& print(bsl::ostream& stream,
635 int level = 0,
636 int spacesPerLevel = 4) const;
637};
638
639// FREE OPERATORS
640
641/// Return `true` if the specified `lhs` and `rhs` objects have the same
642/// value, and `false` otherwise. Two `Zoneinfo` objects have the same
643/// value if the corresponding value of their `identifier` attribute is the
644/// same and if both store the same sequence of transitions, ordered by
645/// time.
646bool operator==(const Zoneinfo& lhs, const Zoneinfo& rhs);
647
648/// Return `true` if the specified `lhs` and `rhs` objects do not have the
649/// same value, and `false` otherwise. Two `Zoneinfo` objects do not have
650/// the same value if their corresponding `identifier` attribute does not
651/// have the same value, or if both do *not* store the same sequence of
652/// transitions, ordered by time.
653bool operator!=(const Zoneinfo& lhs, const Zoneinfo& rhs);
654
655/// Write the value of the specified `object` to the specified output
656/// `stream` in a single-line format, and return a reference to `stream`.
657/// If `stream` is not valid on entry, this operation has no effect. Note
658/// that this human-readable format is not fully specified, can change
659/// without notice, and is logically equivalent to:
660/// @code
661/// print(stream, 0, -1);
662/// @endcode
663bsl::ostream& operator<<(bsl::ostream& stream, const Zoneinfo& object);
664
665// FREE FUNCTIONS
666
667/// Exchange the values of the specified `a` and `b` objects. This function
668/// provides the no-throw exception-safety guarantee if the two objects were
669/// created with the same allocator and the basic guarantee otherwise.
670void swap(Zoneinfo& a, Zoneinfo& b);
671
672// ============================================================================
673// INLINE DEFINITIONS
674// ============================================================================
675
676 // ------------------------
677 // class ZoneinfoTransition
678 // ------------------------
679
680// PRIVATE CREATORS
681inline
682ZoneinfoTransition::ZoneinfoTransition(bdlt::EpochUtil::TimeT64 utcTime,
683 const LocalTimeDescriptor *descriptor)
684: d_utcTime(utcTime)
685, d_descriptor_p(descriptor)
686{
687 BSLS_ASSERT(descriptor);
688}
689
690// CREATORS
691inline
692ZoneinfoTransition::~ZoneinfoTransition()
693{
694 BSLS_ASSERT(d_descriptor_p);
695}
696
697// ACCESSORS
698inline
699const LocalTimeDescriptor& ZoneinfoTransition::descriptor() const
700{
701 return *d_descriptor_p;
702}
703
704inline
705bdlt::EpochUtil::TimeT64 ZoneinfoTransition::utcTime() const
706{
707 return d_utcTime;
708}
709
710} // close package namespace
711
712// FREE OPERATORS
713inline
714bool baltzo::operator==(const ZoneinfoTransition& lhs,
715 const ZoneinfoTransition& rhs)
716{
717 return lhs.utcTime() == rhs.utcTime()
718 && lhs.descriptor() == rhs.descriptor();
719}
720
721inline
722bool baltzo::operator!=(const ZoneinfoTransition& lhs,
723 const ZoneinfoTransition& rhs)
724{
725 return !(lhs == rhs);
726}
727
728inline
729bool baltzo::operator<(const ZoneinfoTransition& lhs,
730 const ZoneinfoTransition& rhs)
731{
732 return lhs.utcTime() < rhs.utcTime();
733}
734
735namespace baltzo {
736
737 // --------------
738 // class Zoneinfo
739 // --------------
740
741// CREATORS
742inline
744: d_identifier()
745, d_descriptors()
746, d_transitions()
747, d_posixExtendedRangeDescription()
748{
749}
750
751inline
753: d_identifier(allocator)
754, d_descriptors(allocator)
755, d_transitions(allocator)
756, d_posixExtendedRangeDescription(allocator)
757{
758}
759
760// MANIPULATORS
761inline
763{
764 Zoneinfo(rhs, get_allocator()).swap(*this);
765 return *this;
766}
767
768inline
770{
771 BSLS_ASSERT(0 != value.data());
772
773 d_identifier = value;
774}
775
776inline
777void Zoneinfo::setIdentifier(const char *value)
778{
779 BSLS_ASSERT(value);
780
781 d_identifier = value;
782}
783
784inline
786{
787 BSLS_ASSERT(0 != value.data());
788
789 d_posixExtendedRangeDescription.assign(value.begin(), value.end());
790}
791
792inline
794{
795 BSLS_ASSERT(value);
796
797 d_posixExtendedRangeDescription = value;
798}
799
800inline
802{
804
805 bslalg::SwapUtil::swap(&d_identifier, &other.d_identifier);
806 bslalg::SwapUtil::swap(&d_descriptors, &other.d_descriptors);
807 bslalg::SwapUtil::swap(&d_transitions, &other.d_transitions);
808 bslalg::SwapUtil::swap(&d_posixExtendedRangeDescription,
809 &other.d_posixExtendedRangeDescription);
810}
811
812// ACCESSORS
813inline
818
819inline
821{
823
824 return d_transitions.front();
825}
826
827inline
829{
830 return d_identifier.get_allocator();
831}
832
833inline
835{
836 return d_identifier;
837}
838
839inline
841{
842 return d_posixExtendedRangeDescription;
843}
844
845inline
846bsl::size_t Zoneinfo::numTransitions() const
847{
848 return d_transitions.size();
849}
850
851inline
853{
854 return d_transitions.begin();
855}
856
857inline
859{
860 return d_transitions.end();
861}
862
863} // close package namespace
864
865// FREE OPERATORS
866inline
867bool baltzo::operator==(const Zoneinfo& lhs, const Zoneinfo& rhs)
868{
869 return lhs.identifier() == rhs.identifier()
870 && lhs.posixExtendedRangeDescription() ==
871 rhs.posixExtendedRangeDescription()
872 && lhs.numTransitions() == rhs.numTransitions()
873 && bsl::equal(lhs.d_transitions.begin(),
874 lhs.d_transitions.end(),
875 rhs.d_transitions.begin());
876}
877
878inline
879bool baltzo::operator!=(const Zoneinfo& lhs, const Zoneinfo& rhs)
880{
881 return !(lhs == rhs);
882}
883
884
885
886#endif
887
888// ----------------------------------------------------------------------------
889// Copyright 2020 Bloomberg Finance L.P.
890//
891// Licensed under the Apache License, Version 2.0 (the "License");
892// you may not use this file except in compliance with the License.
893// You may obtain a copy of the License at
894//
895// http://www.apache.org/licenses/LICENSE-2.0
896//
897// Unless required by applicable law or agreed to in writing, software
898// distributed under the License is distributed on an "AS IS" BASIS,
899// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
900// See the License for the specific language governing permissions and
901// limitations under the License.
902// ----------------------------- END-OF-FILE ----------------------------------
903
904/** @} */
905/** @} */
906/** @} */
Definition baltzo_localtimedescriptor.h:189
Definition baltzo_zoneinfo.h:329
~ZoneinfoTransition()
Destroy this object.
Definition baltzo_zoneinfo.h:692
bdlt::EpochUtil::TimeT64 utcTime() const
Return the value of the utcTime attribute of this object.
Definition baltzo_zoneinfo.h:705
BSLMF_NESTED_TRAIT_DECLARATION(ZoneinfoTransition, bslmf::IsBitwiseMoveable)
const LocalTimeDescriptor & descriptor() const
Definition baltzo_zoneinfo.h:699
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:814
allocator_type get_allocator() const
Definition baltzo_zoneinfo.h:828
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:858
const bsl::string & posixExtendedRangeDescription() const
Definition baltzo_zoneinfo.h:840
Zoneinfo & operator=(bslmf::MovableRef< Zoneinfo > rhs)
void addTransition(bdlt::EpochUtil::TimeT64 utcTime, const LocalTimeDescriptor &descriptor)
TransitionConstIterator beginTransitions() const
Definition baltzo_zoneinfo.h:852
TransitionSequence::const_iterator TransitionConstIterator
Definition baltzo_zoneinfo.h:488
void setPosixExtendedRangeDescription(const bsl::string_view &value)
Definition baltzo_zoneinfo.h:785
Zoneinfo(const Zoneinfo &original, const allocator_type &allocator=allocator_type())
const bsl::string & identifier() const
Definition baltzo_zoneinfo.h:834
void setIdentifier(const bsl::string_view &value)
Definition baltzo_zoneinfo.h:769
void swap(Zoneinfo &other)
Definition baltzo_zoneinfo.h:801
bsl::allocator< char > allocator_type
Definition baltzo_zoneinfo.h:484
bsl::size_t numTransitions() const
Return the number of transitions maintained by this zone info.
Definition baltzo_zoneinfo.h:846
BSLMF_NESTED_TRAIT_DECLARATION(Zoneinfo, bslma::UsesBslmaAllocator)
Zoneinfo & operator=(const Zoneinfo &rhs)
Definition baltzo_zoneinfo.h:762
Zoneinfo()
Definition baltzo_zoneinfo.h:743
const ZoneinfoTransition & firstTransition() const
Definition baltzo_zoneinfo.h:820
Zoneinfo(bslmf::MovableRef< Zoneinfo > original, const allocator_type &allocator)
Definition bdlt_datetime.h:331
Definition bslma_bslallocator.h:580
BloombergLP::bslma::Allocator * mechanism() const
Definition bslma_bslallocator.h:1126
Definition bslstl_stringview.h:441
BSLS_KEYWORD_CONSTEXPR const_iterator end() const BSLS_KEYWORD_NOEXCEPT
Return the past-the-end iterator for this view.
Definition bslstl_stringview.h:1620
BSLS_KEYWORD_CONSTEXPR const_pointer data() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringview.h:1760
BSLS_KEYWORD_CONSTEXPR const_iterator begin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringview.h:1602
Definition bslstl_string.h:1281
basic_string & assign(const basic_string &replacement)
Definition bslstl_string.h:5716
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this string to supply memory.
Definition bslstl_string.h:6723
Definition bslstl_set.h:657
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:2664
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2511
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:2519
reference front()
Definition bslstl_vector.h:2567
Definition bslstl_vector.h:1025
ZoneinfoTransition const * const_iterator
Definition bslstl_vector.h:1058
static void swap(T *a, T *b)
Definition bslalg_swaputil.h:194
Definition bslma_allocator.h:457
Definition bslmf_movableref.h:751
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
Definition baltzo_datafileloader.h:263
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)
bsls::Types::Int64 TimeT64
Definition bdlt_epochutil.h:207
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisemoveable.h:718