AceTime 2.4.0 Date and time classes for Arduino that support timezones from the TZ Database.

Transition.h
1 /*
2 * MIT License
3 * Copyright (c) 2019 Brian T. Park
4 */
5
6 #ifndef ACE_TIME_EXTENDED_TRANSITION_H
7 #define ACE_TIME_EXTENDED_TRANSITION_H
8
9 #include <stdint.h> // uint8_t
10 #include "common/logging.h"
11 #include "local_date_mutation.h"
12 #include "DateTuple.h"
13
14 class TransitionStorageTest_getFreeAgent;
15 class TransitionStorageTest_getFreeAgent2;
16 class TransitionStorageTest_addFreeAgentToActivePool;
17 class TransitionStorageTest_reservePrior;
18 class TransitionStorageTest_addPriorToCandidatePool;
19 class TransitionStorageTest_addFreeAgentToCandidatePool;
20 class TransitionStorageTest_setFreeAgentAsPriorIfValid;
21 class TransitionStorageTest_addActiveCandidatesToActivePool;
22 class TransitionStorageTest_findTransitionForDateTime;
23 class TransitionStorageTest_resetCandidatePool;
24
25 class Print;
26
27 #ifndef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
28 #define ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG 0
29 #endif
30
31 namespace ace_time {
32 namespace extended {
33
34 inline bool isCompareStatusActive(CompareStatus status) {
35 return status == CompareStatus::kExactMatch
36 || status == CompareStatus::kWithinMatch
37 || status == CompareStatus::kPrior;
38 }
39
46 template<typename ZEB>
47 struct MatchingEraTemplate {
52 DateTuple startDateTime;
53
55 DateTuple untilDateTime;
56
58 ZEB era;
59
61 MatchingEraTemplate* prevMatch;
62
64 int32_t lastOffsetSeconds;
65
67 int32_t lastDeltaSeconds;
68
69 void log() const {
70 logging::printf("MatchingEra(");
71 logging::printf("start="); startDateTime.log();
72 logging::printf("; until="); untilDateTime.log();
73 logging::printf("; era=%c", (era.isNull()) ? '-' : '*');
74 logging::printf("; prevMatch=%c", (prevMatch) ? '*' : '-');
75 logging::printf(")");
76 }
77 };
78
79 //---------------------------------------------------------------------------
80
113 template <typename ZEB, typename ZPB, typename ZRB>
114 struct TransitionTemplate {
115
117 const MatchingEraTemplate<ZEB>* match;
118
119 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
126 ZRB rule;
127 #endif
128
135 DateTuple transitionTime;
136
137 union {
143 DateTuple transitionTimeS;
144
149 DateTuple startDateTime;
150 };
151
152 union {
158 DateTuple transitionTimeU;
159
164 DateTuple untilDateTime;
165 };
166
167 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
172 DateTuple originalTransitionTime;
173 #endif
174
176 acetime_t startEpochSeconds;
177
179 int32_t offsetSeconds;
180
182 int32_t deltaSeconds;
183
190 char abbrev[internal::kAbbrevSize];
191
192 union {
199 bool isValidPrior;
200
205 CompareStatus compareStatus;
206 };
207
208 const char* format() const {
209 return match->era.format();
210 }
211
213 void log() const {
214 logging::printf("Transition(");
215 if (sizeof(acetime_t) <= sizeof(int)) {
216 logging::printf("start=%d", startEpochSeconds);
217 } else {
218 logging::printf("start=%ld", startEpochSeconds);
219 }
220 logging::printf("; status=%d", compareStatus);
221 logging::printf("; UTC");
222 logHourMinuteSecond(offsetSeconds);
223 logHourMinuteSecond(deltaSeconds);
224 logging::printf("; tt="); transitionTime.log();
225 logging::printf("; tts="); transitionTimeS.log();
226 logging::printf("; ttu="); transitionTimeU.log();
227 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
228 if (rule.isNull()) {
229 logging::printf("; rule=-");
230 } else {
231 logging::printf("; rule=");
232 logging::printf("[%d,%d]", rule.fromYear(), rule.toYear());
233 }
234 #endif
235 }
236
238 static void logHourMinuteSecond(int32_t seconds) {
239 char sign;
240 if (seconds < 0) {
241 sign = '-';
242 seconds = -seconds;
243 } else {
244 sign = '+';
245 }
246 uint16_t minutes = seconds / 60;
247 uint8_t second = seconds - minutes * int32_t(60);
248 uint8_t hour = minutes / 60;
249 uint8_t minute = minutes - hour * 60;
250 if (second == 0) {
251 logging::printf("%c%02u:%02u", sign, (unsigned) hour, (unsigned) minute);
252 } else {
253 logging::printf("%c%02u:%02u:%02u",
254 sign, (unsigned) hour, (unsigned) minute, (unsigned) second);
255 }
256 }
257
258 #ifdef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
260 static void printTransitions(
261 const char* prefix,
262 const TransitionTemplate* const* begin,
263 const TransitionTemplate* const* end) {
264 for (const TransitionTemplate* const* iter = begin; iter != end; ++iter) {
265 logging::printf(prefix);
266 (*iter)->log();
267 logging::printf("\n");
268 }
269 }
270 #endif
271 };
272
280 template <typename ZEB, typename ZPB, typename ZRB>
281 struct TransitionForSecondsTemplate {
283 const TransitionTemplate<ZEB, ZPB, ZRB>* curr;
284
286 uint8_t fold;
287
294 uint8_t num;
295 };
296
310 template <typename ZEB, typename ZPB, typename ZRB>
311 struct TransitionForDateTimeTemplate {
314 const TransitionTemplate<ZEB, ZPB, ZRB>* prev;
317 const TransitionTemplate<ZEB, ZPB, ZRB>* curr;
318
320 uint8_t num;
321 };
322
354 template<uint8_t SIZE, typename ZEB, typename ZPB, typename ZRB>
355 class TransitionStorageTemplate {
356 public:
361 typedef TransitionTemplate<ZEB, ZPB, ZRB> Transition;
362
368 typedef TransitionForSecondsTemplate<ZEB, ZPB, ZRB> TransitionForSeconds;
369
375 typedef TransitionForDateTimeTemplate<ZEB, ZPB, ZRB> TransitionForDateTime;
376
378 TransitionStorageTemplate() {}
379
386 void init() {
387 for (uint8_t i = 0; i < SIZE; i++) {
388 mTransitions[i] = &mPool[i];
389 }
390 mIndexPrior = 0;
391 mIndexCandidates = 0;
392 mIndexFree = 0;
393 }
394
396 Transition* getPrior() {
397 return mTransitions[mIndexPrior];
398 }
399
408 void resetCandidatePool() {
409 mIndexCandidates = mIndexPrior;
410 mIndexFree = mIndexPrior;
411 }
412
413 Transition** getCandidatePoolBegin() {
414 return &mTransitions[mIndexCandidates];
415 }
416 Transition** getCandidatePoolEnd() {
417 return &mTransitions[mIndexFree];
418 }
419
420 Transition** getActivePoolBegin() {
421 return &mTransitions[0];
422 }
423 Transition** getActivePoolEnd() {
424 return &mTransitions[mIndexFree];
425 }
426
432 Transition* getFreeAgent() {
433 if (mIndexFree < SIZE) {
434 // Allocate a free transition.
435 if (mIndexFree >= mAllocSize) {
436 mAllocSize = mIndexFree + 1;
437 }
438 return mTransitions[mIndexFree];
439 } else {
440 // No more transition available in the buffer, so just return the last
441 // one. This will probably cause a bug in the timezone calculations, but
442 // I think this is better than triggering undefined behavior by running
443 // off the end of the mTransitions buffer.
444 return mTransitions[SIZE - 1];
445 }
446 }
447
455 void addFreeAgentToActivePool() {
456 if (mIndexFree >= SIZE) return;
457 mIndexFree++;
458 mIndexPrior = mIndexFree;
459 mIndexCandidates = mIndexFree;
460 }
461
470 Transition** reservePrior() {
471 getFreeAgent(); // allocate a new Transition
472
473 mIndexCandidates++;
474 mIndexFree++;
475 return &mTransitions[mIndexPrior];
476 }
477
479 void setFreeAgentAsPriorIfValid() {
480 Transition* ft = mTransitions[mIndexFree];
481 Transition* prior = mTransitions[mIndexPrior];
482 if ((prior->isValidPrior && prior->transitionTime < ft->transitionTime)
483 || !prior->isValidPrior) {
484 ft->isValidPrior = true;
485 prior->isValidPrior = false;
486 internal::swap(mTransitions[mIndexPrior], mTransitions[mIndexFree]);
487 }
488 }
489
495 void addPriorToCandidatePool() {
496 mIndexCandidates--;
497 }
498
505 void addFreeAgentToCandidatePool() {
506 if (mIndexFree >= SIZE) return;
507
508 // This implementation makes pair-wise swaps to shift the current
509 // Transition leftwards into its correctly sorted position. At first
510 // glance, this seem inefficient compared to the alternative
511 // implementation where we save the current Transition, then slide all the
512 // elements to the left by one position rightwards. However,
513 // MemoryBenchmark shows that this implementation is 46 bytes smaller on
514 // an AVR processor.
515 for (uint8_t i = mIndexFree; i > mIndexCandidates; i--) {
516 Transition* curr = mTransitions[i];
517 Transition* prev = mTransitions[i - 1];
518 if (curr->transitionTime >= prev->transitionTime) break;
519 mTransitions[i] = prev;
520 mTransitions[i - 1] = curr;
521 }
522 mIndexFree++;
523 }
524
531 Transition* addActiveCandidatesToActivePool() {
532 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
533 logging::printf("addActiveCandidatesToActivePool()\n");
534 }
535
536 // Shift active candidates to the left into the Active pool.
537 uint8_t iActive = mIndexPrior;
538 uint8_t iCandidate = mIndexCandidates;
539 for (; iCandidate < mIndexFree; iCandidate++) {
540 if (isCompareStatusActive(mTransitions[iCandidate]->compareStatus)) {
541 if (iActive != iCandidate) {
542 // Must use swap(), because we are moving pointers instead of the
543 // actual Transition objects.
544 internal::swap(mTransitions[iActive], mTransitions[iCandidate]);
545 }
546 ++iActive;
547 }
548 }
549
550 mIndexPrior = iActive;
551 mIndexCandidates = iActive;
552 mIndexFree = iActive;
553
554 return mTransitions[iActive - 1];
555 }
556
565 TransitionForSeconds findTransitionForSeconds(acetime_t epochSeconds)
566 const {
567 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
568 logging::printf(
569 "findTransitionForSeconds(): mIndexFree: %d\n", mIndexFree);
570 }
571
572 const Transition* prev = nullptr;
573 const Transition* curr = nullptr;
574 const Transition* next = nullptr;
575 for (uint8_t i = 0; i < mIndexFree; i++) {
576 next = mTransitions[i];
577 if (next->startEpochSeconds > epochSeconds) break;
578 prev = curr;
579 curr = next;
580 next = nullptr;
581 }
582
583 uint8_t fold;
584 uint8_t num;
585 calcFoldAndOverlap(&fold, &num, prev, curr, next, epochSeconds);
586 //fprintf(stderr, "prev=%p;curr=%p;next=%p;fold=%d;num=%d\n",
587 // prev, curr, next, fold, num);
588 return TransitionForSeconds{curr, fold, num};
589 }
590
592 static void calcFoldAndOverlap(
593 uint8_t* fold,
594 uint8_t* num,
595 const Transition* prev,
596 const Transition* curr,
597 const Transition* next,
598 acetime_t epochSeconds) {
599
600 if (curr == nullptr) {
601 *fold = 0;
602 *num = 0;
603 return;
604 }
605
606 // Check if within forward overlap shadow from prev
607 bool isOverlap;
608 if (prev == nullptr) {
609 isOverlap = false;
610 } else {
611 // Extract the shift from prev transition. Can be 0 in some cases where
612 // the zone changed from DST of one zone to the STD into another zone,
613 // causing the overall UTC offset to remain unchanged.
614 acetime_t shiftSeconds = subtractDateTuple(
615 curr->startDateTime, prev->untilDateTime);
616 if (shiftSeconds >= 0) {
617 // spring forward, or unchanged
618 isOverlap = false;
619 } else {
620 // Check if within the forward overlap shadow from prev
621 isOverlap = epochSeconds - curr->startEpochSeconds < -shiftSeconds;
622 }
623 }
624 if (isOverlap) {
625 *fold = 1; // epochSeconds selects the second match
626 *num = 2;
627 return;
628 }
629
630 // Check if within backward overlap shawdow from next
631 if (next == nullptr) {
632 isOverlap = false;
633 } else {
634 // Extract the shift to next transition. Can be 0 in some cases where
635 // the zone changed from DST of one zone to the STD into another zone,
636 // causing the overall UTC offset to remain unchanged.
637 acetime_t shiftSeconds = subtractDateTuple(
638 next->startDateTime, curr->untilDateTime);
639 if (shiftSeconds >= 0) {
640 // spring forward, or unchanged
641 isOverlap = false;
642 } else {
643 // Check if within the backward overlap shadow from next
644 isOverlap = next->startEpochSeconds - epochSeconds <= -shiftSeconds;
645 }
646 }
647 if (isOverlap) {
648 *fold = 0; // epochSeconds selects the first match
649 *num = 2;
650 return;
651 }
652
653 // Normal single match, no overlap.
654 *fold = 0;
655 *num = 1;
656 }
657
663 TransitionForDateTime findTransitionForDateTime(
664 const LocalDateTime& ldt) const {
665 // Convert LocalDateTime to DateTuple.
666 DateTuple localDate{
667 ldt.year(),
668 ldt.month(),
669 ldt.day(),
670 ((ldt.hour() * int32_t(60) + ldt.minute()) * 60 + ldt.second()),
671 extended::ZoneContext::kSuffixW,
672 };
673
674 // Examine adjacent pairs of Transitions, looking for an exact match, gap,
675 // or overlap.
676 const Transition* prev = nullptr;
677 const Transition* curr = nullptr;
678 uint8_t num = 0;
679 for (uint8_t i = 0; i < mIndexFree; i++) {
680 curr = mTransitions[i];
681
682 const DateTuple& startDateTime = curr->startDateTime;
683 const DateTuple& untilDateTime = curr->untilDateTime;
684 bool isExactMatch = (startDateTime <= localDate)
685 && (localDate < untilDateTime);
686
687 if (isExactMatch) {
688 // Check for a previous exact match to detect an overlap.
689 if (num == 1) {
690 num++;
691 break;
692 }
693
694 // Loop again to detect an overlap.
695 num = 1;
696 } else if (startDateTime > localDate) {
697 // Exit loop since no more candidate transition.
698 break;
699 }
700
701 prev = curr;
702
703 // Set the curr to nullptr so that if the loop runs off the end of the
704 // list of Transitions, the curr is marked as nullptr.
705 curr = nullptr;
706 }
707
708 // Check if the prev was an exact match, and set the curr to be identical.
709 // avoid confusion.
710 if (num == 1) {
711 curr = prev;
712 }
713
714 // This should get optimized by RVO.
715 return TransitionForDateTime{prev, curr, num};
716 }
717
719 void log() const {
720 logging::printf("TransitionStorage: ");
721 logging::printf("SIZE=%d, mAllocSize=%d\n", SIZE, mAllocSize);
722 int nActives = mIndexPrior;
723 int nPrior = mIndexCandidates - mIndexPrior;
724 int nCandidates = mIndexFree - mIndexCandidates;
725 int nAllocFree = mAllocSize - mIndexFree;
726 int nVirginFree = SIZE - mAllocSize;
727
728 logging::printf(" Actives: %d\n", nActives);
729 Transition::printTransitions(
730 " ", &mTransitions[0], &mTransitions[mIndexPrior]);
731
732 logging::printf(" Prior: %d\n", nPrior);
733 Transition::printTransitions(
734 " ", &mTransitions[mIndexPrior], &mTransitions[mIndexCandidates]);
735
736 logging::printf(" Candidates: %d\n", nCandidates);
737 Transition::printTransitions(
738 " ", &mTransitions[mIndexCandidates], &mTransitions[mIndexFree]);
739
740 logging::printf(" Allocated Free: %d\n", nAllocFree);
741 logging::printf(" Virgin Free: %d\n", nVirginFree);
742 }
743
745 void resetAllocSize() { mAllocSize = 0; }
746
752 uint8_t getAllocSize() const { return mAllocSize; }
753
754 private:
755 friend class ::TransitionStorageTest_getFreeAgent;
756 friend class ::TransitionStorageTest_getFreeAgent2;
757 friend class ::TransitionStorageTest_addFreeAgentToActivePool;
758 friend class ::TransitionStorageTest_reservePrior;
759 friend class ::TransitionStorageTest_addPriorToCandidatePool;
760 friend class ::TransitionStorageTest_addFreeAgentToCandidatePool;
761 friend class ::TransitionStorageTest_setFreeAgentAsPriorIfValid;
762 friend class ::TransitionStorageTest_addActiveCandidatesToActivePool;
763 friend class ::TransitionStorageTest_findTransitionForDateTime;
764 friend class ::TransitionStorageTest_resetCandidatePool;
765
767 Transition* getTransition(uint8_t i) {
768 return mTransitions[i];
769 }
770
771 Transition mPool[SIZE];
772 Transition* mTransitions[SIZE];
773 uint8_t mIndexPrior;
774 uint8_t mIndexCandidates;
775 uint8_t mIndexFree;
776
778 uint8_t mAllocSize = 0;
779 };
780
781 } // namespace extended
782 } // namespace ace_time
783
784 #endif
ace_time::LocalDateTime
Class that holds the date-time as the components (year, month, day, hour, minute, second) without reg...
Definition: LocalDateTime.h:30
ace_time::LocalDateTime::day
uint8_t day() const
Return the day of the month.
Definition: LocalDateTime.h:168
ace_time::LocalDateTime::month
uint8_t month() const
Return the month with January=1, December=12.
Definition: LocalDateTime.h:162
ace_time::LocalDateTime::second
uint8_t second() const
Return the second.
Definition: LocalDateTime.h:186
ace_time::LocalDateTime::minute
uint8_t minute() const
Return the minute.
Definition: LocalDateTime.h:180
ace_time::LocalDateTime::hour
uint8_t hour() const
Return the hour.
Definition: LocalDateTime.h:174
ace_time::LocalDateTime::year
int16_t year() const
Return the year.
Definition: LocalDateTime.h:156
ace_time::extended::TransitionStorageTemplate
A heap manager which is specialized and tuned to manage a collection of Transitions,...
Definition: Transition.h:355
ace_time::extended::TransitionStorageTemplate::resetAllocSize
void resetAllocSize()
Reset the current allocation size.
Definition: Transition.h:745
ace_time::extended::TransitionStorageTemplate::addFreeAgentToActivePool
void addFreeAgentToActivePool()
Immediately add the free agent Transition at index mIndexFree to the Active pool.
Definition: Transition.h:455
ace_time::extended::TransitionStorageTemplate::TransitionForSeconds
TransitionForSecondsTemplate< ZEB, ZPB, ZRB > TransitionForSeconds
Template instantiation of TransitionForSecondsTemplate used by this class.
Definition: Transition.h:368
ace_time::extended::TransitionStorageTemplate::TransitionForDateTime
TransitionForDateTimeTemplate< ZEB, ZPB, ZRB > TransitionForDateTime
Template instantiation of TransitionForDateTimeTemplate used by this class.
Definition: Transition.h:375
ace_time::extended::TransitionStorageTemplate::init
void init()
Initialize all pools to 0 size, usually when a new year is initialized.
Definition: Transition.h:386
ace_time::extended::TransitionStorageTemplate::setFreeAgentAsPriorIfValid
void setFreeAgentAsPriorIfValid()
Set the free agent transition as the most recent prior.
Definition: Transition.h:479
ace_time::extended::TransitionStorageTemplate::getFreeAgent
Transition * getFreeAgent()
Return a pointer to the first Transition in the free pool.
Definition: Transition.h:432
ace_time::extended::TransitionStorageTemplate::Transition
TransitionTemplate< ZEB, ZPB, ZRB > Transition
Template instantiation of TransitionTemplate used by this class.
Definition: Transition.h:361
ace_time::extended::TransitionStorageTemplate::resetCandidatePool
void resetCandidatePool()
Empty the Candidate pool by resetting the various indexes.
Definition: Transition.h:408
ace_time::extended::TransitionStorageTemplate::calcFoldAndOverlap
static void calcFoldAndOverlap(uint8_t *fold, uint8_t *num, const Transition *prev, const Transition *curr, const Transition *next, acetime_t epochSeconds)
Calculate the fold and num parameters of TransitionForSecond.
Definition: Transition.h:592
ace_time::extended::TransitionStorageTemplate::getAllocSize
uint8_t getAllocSize() const
Return the maximum number of transitions which was allocated.
Definition: Transition.h:752
ace_time::extended::TransitionStorageTemplate::addFreeAgentToCandidatePool
void addFreeAgentToCandidatePool()
Add the free agent Transition at index mIndexFree to the Candidate pool, sorted by transitionTime.
Definition: Transition.h:505
ace_time::extended::TransitionStorageTemplate::getPrior
Transition * getPrior()
Return the current prior transition.
Definition: Transition.h:396
ace_time::extended::TransitionStorageTemplate::findTransitionForDateTime
TransitionForDateTime findTransitionForDateTime(const LocalDateTime &ldt) const
Return the candidate Transitions matching the given dateTime.
Definition: Transition.h:663
ace_time::extended::TransitionStorageTemplate::TransitionStorageTemplate
TransitionStorageTemplate()
Constructor.
Definition: Transition.h:378
ace_time::extended::TransitionStorageTemplate::addActiveCandidatesToActivePool
Transition * addActiveCandidatesToActivePool()
Add active candidates into the Active pool, and collapse the Candidate pool.
Definition: Transition.h:531
ace_time::extended::TransitionStorageTemplate::addPriorToCandidatePool
void addPriorToCandidatePool()
Add the current prior into the Candidates pool.
Definition: Transition.h:495
ace_time::extended::TransitionStorageTemplate::findTransitionForSeconds
TransitionForSeconds findTransitionForSeconds(acetime_t epochSeconds) const
Return the Transition matching the given epochSeconds.
Definition: Transition.h:565
ace_time::extended::TransitionStorageTemplate::reservePrior
Transition ** reservePrior()
Allocate a free Transition then add it to the Prior pool.
Definition: Transition.h:470
ace_time::extended::TransitionStorageTemplate::log
void log() const
Verify that the indexes are valid.
Definition: Transition.h:719
ace_time::acetime_t
int32_t acetime_t
Type for the number of seconds from epoch.
Definition: common.h:24
ace_time::extended::DateTuple
A tuple that represents a date and time.
Definition: DateTuple.h:36
ace_time::extended::DateTuple::log
void log() const
Used only for debugging.
Definition: DateTuple.h:50
ace_time::extended::MatchingEraTemplate
Data structure that captures the matching ZoneEra and its ZoneRule transitions for a given year.
Definition: Transition.h:47
ace_time::extended::MatchingEraTemplate::prevMatch
MatchingEraTemplate * prevMatch
The previous MatchingEra, needed to interpret startDateTime.
Definition: Transition.h:61
ace_time::extended::MatchingEraTemplate::era
ZEB era
The ZoneEra that matched the given year.
Definition: Transition.h:58
ace_time::extended::MatchingEraTemplate::untilDateTime
DateTuple untilDateTime
The effective until time of the matching ZoneEra.
Definition: Transition.h:55
ace_time::extended::MatchingEraTemplate::lastOffsetSeconds
int32_t lastOffsetSeconds
The STD offset of the last Transition in this MatchingEra.
Definition: Transition.h:64
ace_time::extended::MatchingEraTemplate::startDateTime
DateTuple startDateTime
The effective start time of the matching ZoneEra, which uses the UTC offsets of the previous matching...
Definition: Transition.h:52
ace_time::extended::MatchingEraTemplate::lastDeltaSeconds
int32_t lastDeltaSeconds
The DST offset of the last Transition in this MatchingEra.
Definition: Transition.h:67
ace_time::extended::TransitionForDateTimeTemplate
The result of the findTransitionForDateTime(const LocalDatetime& ldt) method which can return 0,...
Definition: Transition.h:311
ace_time::extended::TransitionForDateTimeTemplate::num
uint8_t num
Number of matches: 0, 1, 2.
Definition: Transition.h:320
ace_time::extended::TransitionForDateTimeTemplate::prev
const TransitionTemplate< ZEB, ZPB, ZRB > * prev
The previous transition.
Definition: Transition.h:314
ace_time::extended::TransitionForDateTimeTemplate::curr
const TransitionTemplate< ZEB, ZPB, ZRB > * curr
The matching transition, or null if not found or in gap.
Definition: Transition.h:317
ace_time::extended::TransitionForSecondsTemplate
Tuple of a matching Transition and its 'fold'.
Definition: Transition.h:281
ace_time::extended::TransitionForSecondsTemplate::fold
uint8_t fold
1 if corresponding datetime occurred the second time
Definition: Transition.h:286
ace_time::extended::TransitionForSecondsTemplate::curr
const TransitionTemplate< ZEB, ZPB, ZRB > * curr
The matching transition, or null if not found.
Definition: Transition.h:283
ace_time::extended::TransitionForSecondsTemplate::num
uint8_t num
Number of occurrences of the resulting LocalDateTime: 0, 1, or 2.
Definition: Transition.h:294
ace_time::extended::TransitionTemplate
Represents an interval of time where the time zone obeyed a certain UTC offset and DST delta.
Definition: Transition.h:114
ace_time::extended::TransitionTemplate::printTransitions
static void printTransitions(const char *prefix, const TransitionTemplate *const *begin, const TransitionTemplate *const *end)
Print an iterable of Transitions from 'begin' to 'end'.
Definition: Transition.h:260
ace_time::extended::TransitionTemplate::offsetSeconds
int32_t offsetSeconds
The standard time offset seconds, not the total offset.
Definition: Transition.h:179
ace_time::extended::TransitionTemplate::isValidPrior
bool isValidPrior
During findCandidateTransitions(), this flag indicates whether the current transition is a valid "pri...
Definition: Transition.h:199
ace_time::extended::TransitionTemplate::transitionTime
DateTuple transitionTime
The original transition time, usually 'w' but sometimes 's' or 'u'.
Definition: Transition.h:135
ace_time::extended::TransitionTemplate::startEpochSeconds
acetime_t startEpochSeconds
The calculated transition time of the given rule.
Definition: Transition.h:176
ace_time::extended::TransitionTemplate::transitionTimeS
DateTuple transitionTimeS
Version of transitionTime in 's' mode, using the UTC offset of the previous Transition.
Definition: Transition.h:143
ace_time::extended::TransitionTemplate::untilDateTime
DateTuple untilDateTime
Until time expressed using the UTC offset of the current Transition.
Definition: Transition.h:164
ace_time::extended::TransitionTemplate::log
void log() const
Used only for debugging.
Definition: Transition.h:213
ace_time::extended::TransitionTemplate::transitionTimeU
DateTuple transitionTimeU
Version of transitionTime in 'u' mode, using the UTC offset of the previous transition.
Definition: Transition.h:158
ace_time::extended::TransitionTemplate::compareStatus
CompareStatus compareStatus
During processTransitionCompareStatus(), this flag indicates how the transition falls within the time...
Definition: Transition.h:205
ace_time::extended::TransitionTemplate::deltaSeconds
int32_t deltaSeconds
The DST delta seconds.
Definition: Transition.h:182
ace_time::extended::TransitionTemplate::startDateTime
DateTuple startDateTime
Start time expressed using the UTC offset of the current Transition.
Definition: Transition.h:149
ace_time::extended::TransitionTemplate::abbrev
char abbrev[internal::kAbbrevSize]
The calculated effective time zone abbreviation, e.g.
Definition: Transition.h:190
ace_time::extended::TransitionTemplate::logHourMinuteSecond
static void logHourMinuteSecond(int32_t seconds)
Print seconds as [+/-]hh:mm[:ss].
Definition: Transition.h:238
ace_time::extended::TransitionTemplate::match
const MatchingEraTemplate< ZEB > * match
The match which generated this Transition.
Definition: Transition.h:117
ace_time::zoneinfolow::ZoneContext::kSuffixW
static const uint8_t kSuffixW
Represents 'w' or wall time.
Definition: ZoneInfoLow.h:80