6 #ifndef ACE_TIME_EXTENDED_ZONE_PROCESSOR_H
7 #define ACE_TIME_EXTENDED_ZONE_PROCESSOR_H
10 #include <AceCommon.h>
11 #include "../zoneinfo/infos.h"
12 #include "../zoneinfo/brokers.h"
14 #include "common/logging.h"
15 #include "LocalDate.h"
16 #include "ZoneProcessor.h"
17 #include "Transition.h"
19 #ifndef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
20 #define ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG 0
23 class ExtendedZoneProcessorTest_compareEraToYearMonth;
24 class ExtendedZoneProcessorTest_compareEraToYearMonth2;
25 class ExtendedZoneProcessorTest_createMatchingEra;
26 class ExtendedZoneProcessorTest_findMatches_simple;
27 class ExtendedZoneProcessorTest_findMatches_named;
28 class ExtendedZoneProcessorTest_findCandidateTransitions;
29 class ExtendedZoneProcessorTest_createTransitionsFromNamedMatch;
30 class ExtendedZoneProcessorTest_getTransitionTime;
31 class ExtendedZoneProcessorTest_createTransitionForYear;
32 class ExtendedZoneProcessorTest_calcInteriorYears;
33 class ExtendedZoneProcessorTest_getMostRecentPriorYear;
34 class ExtendedZoneProcessorTest_compareTransitionToMatchFuzzy;
35 class ExtendedZoneProcessorTest_compareTransitionToMatch;
36 class ExtendedZoneProcessorTest_processTransitionCompareStatus;
37 class ExtendedZoneProcessorTest_fixTransitionTimes_generateStartUntilTimes;
38 class ExtendedZoneProcessorTest_setZoneKey;
39 class ExtendedTransitionValidation;
40 class CompleteTransitionValidation;
87 template <
typename ZIS,
typename ZIB,
typename ZEB,
typename ZPB,
typename ZRB>
122 return ! mZoneInfoBroker.targetInfo().isNull();
126 return mZoneInfoBroker.zoneId();
144 if (transitionForDateTime.
num == 1) {
145 transition = transitionForDateTime.
curr;
146 result.
type = FindResult::kTypeExact;
150 if (transitionForDateTime.
prev ==
nullptr
151 || transitionForDateTime.
curr ==
nullptr) {
153 transition =
nullptr;
154 result.
type = FindResult::kTypeNotFound;
156 if (transitionForDateTime.
num == 0) {
157 result.
type = FindResult::kTypeGap;
158 if (ldt.
fold() == 0) {
162 transitionForDateTime.
prev->offsetSeconds;
164 transitionForDateTime.
prev->deltaSeconds;
167 transition = transitionForDateTime.
curr;
172 transitionForDateTime.
curr->offsetSeconds;
174 transitionForDateTime.
curr->deltaSeconds;
177 transition = transitionForDateTime.
prev;
180 transition = (ldt.
fold() == 0)
181 ? transitionForDateTime.
prev
182 : transitionForDateTime.
curr;
183 result.
type = FindResult::kTypeOverlap;
213 if (!success)
return result;
218 if (!transition)
return result;
225 result.
fold = transitionForSeconds.
fold;
226 if (transitionForSeconds.
num == 2) {
227 result.
type = FindResult::kTypeOverlap;
229 result.
type = FindResult::kTypeExact;
235 mZoneInfoBroker.printNameTo(printer);
239 mZoneInfoBroker.printShortNameTo(printer);
244 mZoneInfoBroker.targetInfo().printNameTo(printer);
250 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
251 logging::printf(
"ExtendedZoneProcessor:\n");
252 logging::printf(
" mEpochYear: %d\n",
mEpochYear);
253 logging::printf(
" mYear: %d\n",
mYear);
254 logging::printf(
" mNumMatches: %d\n", mNumMatches);
255 for (
int i = 0; i < mNumMatches; i++) {
256 logging::printf(
" Match %d: ", i);
258 logging::printf(
"\n");
260 mTransitionStorage.
log();
275 if (! mZoneInfoStore)
return;
276 if (mZoneInfoBroker.equals(zoneKey))
return;
278 mZoneInfoBroker = mZoneInfoStore->createZoneInfoBroker(zoneKey);
285 return mZoneInfoBroker.equals(zoneKey);
295 mZoneInfoStore = zoneInfoStore;
317 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
319 "initForYear(): Year %d outside range [%d, %d]\n",
326 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
327 logging::printf(
"initForYear(): %d\n", year);
332 mTransitionStorage.
init();
340 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
341 logging::printf(
"==== Step 1: findMatches()\n");
343 mNumMatches = findMatches(mZoneInfoBroker, startYm, untilYm, mMatches,
345 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
348 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
349 logging::printf(
"==== Step 2: createTransitions()\n");
351 createTransitions(mTransitionStorage, mMatches, mNumMatches);
352 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
355 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
356 logging::printf(
"==== Step 3: fixTransitionTimes()\n");
358 Transition** begin = mTransitionStorage.getActivePoolBegin();
359 Transition** end = mTransitionStorage.getActivePoolEnd();
360 fixTransitionTimes(begin, end);
361 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
364 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
365 logging::printf(
"==== Step 4: generateStartUntilTimes()\n");
367 generateStartUntilTimes(begin, end);
368 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
371 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
372 logging::printf(
"==== Step 5: calcAbbreviations()\n");
374 calcAbbreviations(begin, end);
375 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
393 const ZIS* zoneInfoStore ,
397 mZoneInfoStore(zoneInfoStore)
403 friend class ::ExtendedZoneProcessorTest_compareEraToYearMonth;
404 friend class ::ExtendedZoneProcessorTest_compareEraToYearMonth2;
405 friend class ::ExtendedZoneProcessorTest_createMatchingEra;
406 friend class ::ExtendedZoneProcessorTest_findMatches_simple;
407 friend class ::ExtendedZoneProcessorTest_findMatches_named;
408 friend class ::ExtendedZoneProcessorTest_findCandidateTransitions;
409 friend class ::ExtendedZoneProcessorTest_createTransitionsFromNamedMatch;
410 friend class ::ExtendedZoneProcessorTest_getTransitionTime;
411 friend class ::ExtendedZoneProcessorTest_createTransitionForYear;
412 friend class ::ExtendedZoneProcessorTest_calcInteriorYears;
413 friend class ::ExtendedZoneProcessorTest_getMostRecentPriorYear;
414 friend class ::ExtendedZoneProcessorTest_compareTransitionToMatchFuzzy;
415 friend class ::ExtendedZoneProcessorTest_compareTransitionToMatch;
416 friend class ::ExtendedZoneProcessorTest_processTransitionCompareStatus;
417 friend class ::ExtendedZoneProcessorTest_fixTransitionTimes_generateStartUntilTimes;
418 friend class ::ExtendedZoneProcessorTest_setZoneKey;
419 friend class ::ExtendedTransitionValidation;
420 friend class ::CompleteTransitionValidation;
432 static const uint8_t kMaxMatches = 4;
438 static const uint8_t kMaxInteriorYears = 4;
441 return mZoneInfoBroker.equals(
452 static uint8_t findMatches(
454 const extended::YearMonthTuple& startYm,
455 const extended::YearMonthTuple& untilYm,
459 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
460 logging::printf(
"findMatches()\n");
464 for (uint8_t iEra = 0; iEra < zoneInfo.numEras(); iEra++) {
465 const ZEB era = zoneInfo.era(iEra);
466 if (eraOverlapsInterval(prevMatch, era, startYm, untilYm)) {
467 if (iMatch < maxMatches) {
468 matches[iMatch] = createMatchingEra(
469 prevMatch, era, startYm, untilYm);
470 prevMatch = &matches[iMatch];
503 static bool eraOverlapsInterval(
506 const extended::YearMonthTuple& startYm,
507 const extended::YearMonthTuple& untilYm) {
508 return (prevMatch ==
nullptr || compareEraToYearMonth(
509 prevMatch->era, untilYm.year, untilYm.month) < 0)
510 && compareEraToYearMonth(era, startYm.year, startYm.month) > 0;
514 static int8_t compareEraToYearMonth(
const ZEB& era,
515 int16_t year, uint8_t month) {
516 if (era.untilYear() < year)
return -1;
517 if (era.untilYear() > year)
return 1;
518 if (era.untilMonth() < month)
return -1;
519 if (era.untilMonth() > month)
return 1;
520 if (era.untilDay() > 1)
return 1;
522 if (era.untilTimeSeconds() > 0)
return 1;
535 const extended::YearMonthTuple& startYm,
536 const extended::YearMonthTuple& untilYm) {
540 extended::DateTuple startDate = (prevMatch ==
nullptr)
541 ? extended::DateTuple{
548 : extended::DateTuple{
549 prevMatch->era.untilYear(),
550 prevMatch->era.untilMonth(),
551 prevMatch->era.untilDay(),
552 (int32_t) prevMatch->era.untilTimeSeconds(),
553 prevMatch->era.untilTimeSuffix()
555 extended::DateTuple lowerBound{
562 if (startDate < lowerBound) {
563 startDate = lowerBound;
566 extended::DateTuple untilDate{
570 (int32_t) era.untilTimeSeconds(),
571 era.untilTimeSuffix()
573 extended::DateTuple upperBound{
580 if (upperBound < untilDate) {
581 untilDate = upperBound;
584 return {startDate, untilDate, era, prevMatch, 0, 0};
591 static void createTransitions(
594 uint8_t numMatches) {
595 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
596 logging::printf(
"createTransitions()\n");
599 for (uint8_t i = 0; i < numMatches; i++) {
600 createTransitionsForMatch(transitionStorage, &matches[i]);
605 static void createTransitionsForMatch(
608 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
609 logging::printf(
"== createTransitionsForMatch()\n");
611 const ZPB policy = match->era.zonePolicy();
612 if (policy.isNull()) {
613 createTransitionsFromSimpleMatch(transitionStorage, match);
615 createTransitionsFromNamedMatch(transitionStorage, match);
620 static void createTransitionsFromSimpleMatch(
623 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
624 logging::printf(
"== createTransitionsFromSimpleMatch()\n");
627 Transition* freeTransition = transitionStorage.getFreeAgent();
628 createTransitionForYear(freeTransition, 0 ,
630 freeTransition->compareStatus = extended::CompareStatus::kExactMatch;
631 match->lastOffsetSeconds = freeTransition->offsetSeconds;
632 match->lastDeltaSeconds = freeTransition->deltaSeconds;
633 transitionStorage.addFreeAgentToActivePool();
634 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
635 transitionStorage.log();
640 static void createTransitionsFromNamedMatch(
643 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
644 logging::printf(
"== createTransitionsFromNamedMatch()\n");
647 transitionStorage.resetCandidatePool();
648 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
649 match->log(); logging::printf(
"\n");
653 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
654 logging::printf(
"---- Pass 1: findCandidateTransitions()\n");
656 findCandidateTransitions(transitionStorage, match);
657 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
658 transitionStorage.log();
663 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
664 logging::printf(
"---- Pass 2: fixTransitionTimes()\n");
667 transitionStorage.getCandidatePoolBegin(),
668 transitionStorage.getCandidatePoolEnd());
672 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
673 logging::printf(
"---- Pass 3: selectActiveTransitions()\n");
675 selectActiveTransitions(
676 transitionStorage.getCandidatePoolBegin(),
677 transitionStorage.getCandidatePoolEnd());
678 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
679 transitionStorage.log();
682 transitionStorage.addActiveCandidatesToActivePool();
683 match->lastOffsetSeconds = lastTransition->offsetSeconds;
684 match->lastDeltaSeconds = lastTransition->deltaSeconds;
685 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
686 transitionStorage.log();
691 static void findCandidateTransitions(
694 using extended::CompareStatus;
696 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
697 logging::printf(
"findCandidateTransitions(): \n");
699 logging::printf(
"\n");
701 const ZPB policy = match->era.zonePolicy();
702 uint8_t numRules = policy.numRules();
703 int16_t startY = match->startDateTime.year;
704 int16_t endY = match->untilDateTime.year;
709 Transition** prior = transitionStorage.reservePrior();
710 (*prior)->isValidPrior =
false;
711 for (uint8_t r = 0; r < numRules; r++) {
712 const ZRB rule = policy.rule(r);
715 int16_t interiorYears[kMaxInteriorYears];
716 uint8_t numYears = calcInteriorYears(interiorYears, kMaxInteriorYears,
717 rule.fromYear(), rule.toYear(), startY, endY);
718 for (uint8_t y = 0; y < numYears; y++) {
719 int16_t year = interiorYears[y];
720 Transition* t = transitionStorage.getFreeAgent();
721 createTransitionForYear(t, year, rule, match);
722 CompareStatus status = compareTransitionToMatchFuzzy(t, match);
723 if (status == CompareStatus::kPrior) {
724 transitionStorage.setFreeAgentAsPriorIfValid();
725 }
else if (status == CompareStatus::kWithinMatch) {
726 transitionStorage.addFreeAgentToCandidatePool();
734 int16_t priorYear = getMostRecentPriorYear(
735 rule.fromYear(), rule.toYear(), startY, endY);
737 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
739 "findCandidateTransitions(): priorYear: %d\n", priorYear);
741 Transition* t = transitionStorage.getFreeAgent();
742 createTransitionForYear(t, priorYear, rule, match);
743 transitionStorage.setFreeAgentAsPriorIfValid();
749 if ((*prior)->isValidPrior) {
750 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
752 "findCandidateTransitions(): adding prior to Candidate pool\n");
753 logging::printf(
" ");
755 logging::printf(
"\n");
757 transitionStorage.addPriorToCandidatePool();
780 static uint8_t calcInteriorYears(
781 int16_t* interiorYears,
782 uint8_t maxInteriorYears,
783 int16_t fromYear, int16_t toYear,
784 int16_t startYear, int16_t endYear) {
786 for (int16_t year = startYear; year <= endYear; year++) {
787 if (fromYear <= year && year <= toYear) {
788 interiorYears[i] = year;
790 if (i >= maxInteriorYears)
break;
801 static void createTransitionForYear(
807 t->offsetSeconds = match->era.offsetSeconds();
808 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
815 t->transitionTime = match->startDateTime;
816 t->deltaSeconds = match->era.deltaSeconds();
819 t->transitionTime = getTransitionTime(year, rule);
820 t->deltaSeconds = rule.deltaSeconds();
821 ace_common::strncpy_T(
822 t->abbrev, rule.letter(), internal::kAbbrevSize - 1);
823 t->abbrev[internal::kAbbrevSize - 1] =
'\0';
839 static int16_t getMostRecentPriorYear(
840 int16_t fromYear, int16_t toYear,
841 int16_t startYear, int16_t ) {
843 if (fromYear < startYear) {
844 if (toYear < startYear) {
847 return startYear - 1;
858 static extended::DateTuple getTransitionTime(
859 int16_t year,
const ZRB& rule) {
861 internal::MonthDay monthDay = internal::calcStartDayOfMonth(
865 rule.onDayOfMonth());
870 (int32_t) rule.atTimeSeconds(),
885 static extended::CompareStatus compareTransitionToMatchFuzzy(
887 return compareDateTupleFuzzy(
889 match->startDateTime,
890 match->untilDateTime);
902 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
903 logging::printf(
"fixTransitionTimes(): START; #transitions=%d\n",
904 (
int) (end - begin));
911 for (
Transition** iter = begin; iter != end; ++iter) {
914 &curr->transitionTime,
917 &curr->transitionTime,
918 &curr->transitionTimeS,
919 &curr->transitionTimeU);
922 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
923 logging::printf(
"fixTransitionTimes(): FIXED\n");
925 logging::printf(
"fixTransitionTimes(): END\n");
934 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
935 logging::printf(
"selectActiveTransitions(): #candidates: %d\n",
936 (
int) (end - begin));
940 for (
Transition** iter = begin; iter != end; ++iter) {
942 processTransitionCompareStatus(transition, &prior);
948 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
950 "selectActiveTransitions(): found latest prior\n");
952 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
953 prior->originalTransitionTime = prior->transitionTime;
955 prior->transitionTime = prior->match->startDateTime;
965 static void processTransitionCompareStatus(
968 using extended::CompareStatus;
970 CompareStatus status = compareTransitionToMatch(
971 transition, transition->match);
972 transition->compareStatus = status;
974 if (status == CompareStatus::kExactMatch) {
976 (*prior)->compareStatus = CompareStatus::kFarPast;
978 (*prior) = transition;
979 }
else if (status == CompareStatus::kPrior) {
981 if ((*prior)->transitionTimeU <= transition->transitionTimeU) {
982 (*prior)->compareStatus = CompareStatus::kFarPast;
983 (*prior) = transition;
985 transition->compareStatus = CompareStatus::kFarPast;
988 (*prior) = transition;
1001 static extended::CompareStatus compareTransitionToMatch(
1006 int32_t prevMatchOffsetSeconds;
1007 int32_t prevMatchDeltaSeconds;
1008 if (match->prevMatch) {
1009 prevMatchOffsetSeconds = match->prevMatch->lastOffsetSeconds;
1010 prevMatchDeltaSeconds = match->prevMatch->lastDeltaSeconds;
1012 prevMatchOffsetSeconds = match->era.offsetSeconds();
1013 prevMatchDeltaSeconds = 0;
1017 extended::DateTuple stw;
1018 extended::DateTuple sts;
1019 extended::DateTuple stu;
1021 &match->startDateTime,
1022 prevMatchOffsetSeconds,
1023 prevMatchDeltaSeconds,
1029 const extended::DateTuple& ttw = transition->transitionTime;
1030 const extended::DateTuple& tts = transition->transitionTimeS;
1031 const extended::DateTuple& ttu = transition->transitionTimeU;
1036 if (ttw == stw || tts == sts || ttu == stu) {
1037 return extended::CompareStatus::kExactMatch;
1041 return extended::CompareStatus::kPrior;
1049 const extended::DateTuple& matchUntil = match->untilDateTime;
1050 const extended::DateTuple* transitionTime;
1052 transitionTime = &tts;
1054 transitionTime = &ttu;
1056 transitionTime = &ttw;
1058 if (*transitionTime < matchUntil) {
1059 return extended::CompareStatus::kWithinMatch;
1061 return extended::CompareStatus::kFarFuture;
1070 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
1072 "generateStartUntilTimes(): #transitions=%d\n",
1073 (
int) (end - begin));
1078 if (begin == end)
return;
1081 bool isAfterFirst =
false;
1083 for (
Transition** iter = begin; iter != end; ++iter) {
1087 const extended::DateTuple& tt = t->transitionTime;
1089 prev->untilDateTime = tt;
1095 int32_t seconds = tt.seconds + (
1096 - prev->offsetSeconds - prev->deltaSeconds
1097 + t->offsetSeconds + t->deltaSeconds);
1098 t->startDateTime = {tt.year, tt.month, tt.day, seconds, tt.suffix};
1099 extended::normalizeDateTuple(&t->startDateTime);
1111 const extended::DateTuple& st = t->startDateTime;
1113 st.seconds - (t->offsetSeconds + t->deltaSeconds);
1115 t->startEpochSeconds = ld.toEpochSeconds() + offsetSeconds;
1118 isAfterFirst =
true;
1122 extended::DateTuple untilTimeW;
1123 extended::DateTuple untilTimeS;
1124 extended::DateTuple untilTimeU;
1126 &prev->match->untilDateTime,
1127 prev->offsetSeconds,
1132 prev->untilDateTime = untilTimeW;
1139 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
1140 logging::printf(
"calcAbbreviations(): #transitions: %d\n",
1141 (
int) (end - begin));
1143 for (
Transition** iter = begin; iter != end; ++iter) {
1145 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
1147 "calcAbbreviations(): format:%s, deltaSeconds:%d, letter:%s\n",
1148 t->format(), t->deltaSeconds, t->abbrev);
1150 internal::createAbbreviation(
1152 internal::kAbbrevSize,
1160 const ZIS* mZoneInfoStore;
1161 ZIB mZoneInfoBroker;
1164 mutable uint8_t mNumMatches = 0;
1175 extended::ZoneInfoStore,
1176 extended::ZoneInfoBroker,
1177 extended::ZoneEraBroker,
1178 extended::ZonePolicyBroker,
1179 extended::ZoneRuleBroker> {
1187 extended::ZoneInfoStore,
1188 extended::ZoneInfoBroker,
1189 extended::ZoneEraBroker,
1190 extended::ZonePolicyBroker,
1191 extended::ZoneRuleBroker>(
static int16_t currentEpochYear()
Get the current epoch year.
An implementation of ZoneProcessor that supports for all zones defined by the TZ Database.
extended::TransitionForSecondsTemplate< ZEB, ZPB, ZRB > TransitionForSeconds
Exposed only for testing purposes.
bool equalsZoneKey(uintptr_t zoneKey) const override
Return true if ZoneProcessor is associated with the given opaque zoneKey.
FindResult findByLocalDateTime(const LocalDateTime &ldt) const override
Return the search results at given LocalDateTime.
extended::MatchingEraTemplate< ZEB > MatchingEra
Exposed only for testing purposes.
extended::TransitionTemplate< ZEB, ZPB, ZRB > Transition
Exposed only for testing purposes.
void printTargetNameTo(Print &printer) const override
Print the full identifier (e.g.
ExtendedZoneProcessorTemplate(uint8_t type, const ZIS *zoneInfoStore, uintptr_t zoneKey)
Constructor.
void setZoneKey(uintptr_t zoneKey) override
Set the opaque zoneKey of this object to a new value, reseting any internally cached information.
extended::TransitionForDateTimeTemplate< ZEB, ZPB, ZRB > TransitionForDateTime
Exposed only for testing purposes.
void printNameTo(Print &printer) const override
Print a human-readable identifier (e.g.
uint32_t getZoneId() const override
Return the unique stable zoneId.
bool initForEpochSeconds(acetime_t epochSeconds) const
Initialize using the epochSeconds.
FindResult findByEpochSeconds(acetime_t epochSeconds) const override
void log() const
Used only for debugging.
void setZoneInfoStore(const ZIS *zoneInfoStore)
Set the zone info store at runtime.
uint8_t getTransitionAllocSize() const
Get the largest allocation size of TransitionStorage.
static const uint8_t kMaxTransitions
Max number of Transitions required for all Zones supported by this class.
void printShortNameTo(Print &printer) const override
Print a short human-readable identifier (e.g.
extended::TransitionStorageTemplate< kMaxTransitions, ZEB, ZPB, ZRB > TransitionStorage
Exposed only for testing purposes.
bool isLink() const override
Return true if timezone is a Link entry pointing to a Zone entry.
void resetTransitionAllocSize()
Reset the TransitionStorage high water mark.
bool initForYear(int16_t year) const
Initialize the zone rules cache, keyed by the "current" year.
A specific implementation of ExtendedZoneProcessorTemplate that uses the extended::ZoneXxxBrokers cla...
static const uint8_t kTypeExtended
Unique TimeZone type identifier for ExtendedZoneProcessor.
Result of a search for transition at a specific epochSeconds or a specific LocalDateTime.
uint8_t fold
For findByLocalDateTime(), when type==kTypeOverlap, this is a copy of the requested LocalDateTime::fo...
int32_t stdOffsetSeconds
STD offset of the resulting OffsetDateTime.
int32_t dstOffsetSeconds
DST offset of the resulting OffsetDateTime.
int32_t reqDstOffsetSeconds
DST offset of the Transition which matched the epochSeconds requested by findByEpochSeconds(),...
const char * abbrev
Pointer to the abbreviation stored in the transient Transition::abbrev variable.
int32_t reqStdOffsetSeconds
STD offset of the Transition which matched the epochSeconds requested by findByEpochSeconds(),...
uint8_t type
Result of the findByEpochSeconds() or findByLocalDateTime() search methods.
Class that holds the date-time as the components (year, month, day, hour, minute, second) without reg...
uint8_t fold() const
Return the fold.
int16_t year() const
Return the year.
The date (year, month, day) representing the date without regards to time zone.
static LocalDate forComponents(int16_t year, uint8_t month, uint8_t day)
Factory method using separated year, month and day fields.
static const int16_t kMaxYear
The largest year that is expected to be handled by LocalDate.
static const int16_t kMinYear
The smallest year that is expected to be handled by LocalDate.
int16_t year() const
Return the year.
static LocalDate forEpochSeconds(acetime_t epochSeconds)
Factory method using the number of seconds since the current epoch year given by currentEpochYear().
static const int16_t kInvalidYear
Sentinel year which indicates one or more of the following conditions:
Base interface for ZoneProcessor classes.
int16_t mYear
Year that was used to calculate the transitions in the current cache.
bool isFilled(int16_t year) const
Check if the Transition cache is filled for the given year and current epochYear.
int16_t mEpochYear
Epoch year that was used to calculate the transitions in the current cache.
void resetAllocSize()
Reset the current allocation size.
void init()
Initialize all pools to 0 size, usually when a new year is initialized.
uint8_t getAllocSize() const
Return the maximum number of transitions which was allocated.
TransitionForDateTime findTransitionForDateTime(const LocalDateTime &ldt) const
Return the candidate Transitions matching the given dateTime.
TransitionForSeconds findTransitionForSeconds(acetime_t epochSeconds) const
Return the Transition matching the given epochSeconds.
void log() const
Verify that the indexes are valid.
Identifiers used by implementation code which need to be publically exported.
int32_t acetime_t
Type for the number of seconds from epoch.
Data structure that captures the matching ZoneEra and its ZoneRule transitions for a given year.
The result of the findTransitionForDateTime(const LocalDatetime& ldt) method which can return 0,...
uint8_t num
Number of matches: 0, 1, 2.
const TransitionTemplate< ZEB, ZPB, ZRB > * prev
The previous transition.
const TransitionTemplate< ZEB, ZPB, ZRB > * curr
The matching transition, or null if not found or in gap.
Tuple of a matching Transition and its 'fold'.
uint8_t fold
1 if corresponding datetime occurred the second time
const TransitionTemplate< ZEB, ZPB, ZRB > * curr
The matching transition, or null if not found.
uint8_t num
Number of occurrences of the resulting LocalDateTime: 0, 1, or 2.
Represents an interval of time where the time zone obeyed a certain UTC offset and DST delta.
static void printTransitions(const char *prefix, const TransitionTemplate *const *begin, const TransitionTemplate *const *end)
Print an iterable of Transitions from 'begin' to 'end'.
int32_t offsetSeconds
The base offset minutes, not the total effective UTC offset.
int32_t deltaSeconds
The DST delta seconds.
char abbrev[internal::kAbbrevSize]
The calculated effective time zone abbreviation, e.g.
A simple tuple to represent a year/month pair.
static const uint8_t kSuffixS
Represents 's' or standard time.
static const uint8_t kSuffixW
Represents 'w' or wall time.
static const uint8_t kSuffixU
Represents 'u' or UTC time.
Representation of a given time zone, implemented as an array of ZoneEra records.