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"
13 #include "common/logging.h"
14 #include "LocalDate.h"
15 #include "ZoneProcessor.h"
16 #include "Transition.h"
18 #ifndef ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
19 #define ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG 0
22 class ExtendedZoneProcessorTest_compareEraToYearMonth;
23 class ExtendedZoneProcessorTest_compareEraToYearMonth2;
24 class ExtendedZoneProcessorTest_createMatchingEra;
25 class ExtendedZoneProcessorTest_findMatches_simple;
26 class ExtendedZoneProcessorTest_findMatches_named;
27 class ExtendedZoneProcessorTest_findCandidateTransitions;
28 class ExtendedZoneProcessorTest_createTransitionsFromNamedMatch;
29 class ExtendedZoneProcessorTest_getTransitionTime;
30 class ExtendedZoneProcessorTest_createTransitionForYear;
31 class ExtendedZoneProcessorTest_calcInteriorYears;
32 class ExtendedZoneProcessorTest_getMostRecentPriorYear;
33 class ExtendedZoneProcessorTest_compareTransitionToMatchFuzzy;
34 class ExtendedZoneProcessorTest_compareTransitionToMatch;
35 class ExtendedZoneProcessorTest_processTransitionCompareStatus;
36 class ExtendedZoneProcessorTest_fixTransitionTimes_generateStartUntilTimes;
37 class ExtendedZoneProcessorTest_setZoneKey;
38 class ExtendedTransitionValidation;
39 class CompleteTransitionValidation;
115 return ! mZoneInfoBroker.targetInfo().isNull();
119 return mZoneInfoBroker.zoneId();
137 if (transitionForDateTime.
num == 1) {
138 transition = transitionForDateTime.
curr;
139 result.
type = FindResult::kTypeExact;
143 if (transitionForDateTime.
prev ==
nullptr
144 || transitionForDateTime.
curr ==
nullptr) {
146 transition =
nullptr;
147 result.
type = FindResult::kTypeNotFound;
149 if (transitionForDateTime.
num == 0) {
150 result.
type = FindResult::kTypeGap;
151 if (ldt.
fold() == 0) {
155 transitionForDateTime.
prev->offsetSeconds;
157 transitionForDateTime.
prev->deltaSeconds;
160 transition = transitionForDateTime.
curr;
165 transitionForDateTime.
curr->offsetSeconds;
167 transitionForDateTime.
curr->deltaSeconds;
170 transition = transitionForDateTime.
prev;
173 transition = (ldt.
fold() == 0)
174 ? transitionForDateTime.
prev
175 : transitionForDateTime.
curr;
176 result.
type = FindResult::kTypeOverlap;
206 if (!success)
return result;
211 if (!transition)
return result;
218 result.
fold = transitionForSeconds.
fold;
219 if (transitionForSeconds.
num == 2) {
220 result.
type = FindResult::kTypeOverlap;
222 result.
type = FindResult::kTypeExact;
228 mZoneInfoBroker.printNameTo(printer);
232 mZoneInfoBroker.printShortNameTo(printer);
237 mZoneInfoBroker.targetInfo().printNameTo(printer);
243 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
244 logging::printf(
"ExtendedZoneProcessor:\n");
245 logging::printf(
" mEpochYear: %d\n",
mEpochYear);
246 logging::printf(
" mYear: %d\n",
mYear);
247 logging::printf(
" mNumMatches: %d\n", mNumMatches);
248 for (
int i = 0; i < mNumMatches; i++) {
249 logging::printf(
" Match %d: ", i);
251 logging::printf(
"\n");
253 mTransitionStorage.
log();
268 if (! mZoneInfoStore)
return;
269 if (mZoneInfoBroker.equals(zoneKey))
return;
271 mZoneInfoBroker = mZoneInfoStore->createZoneInfoBroker(zoneKey);
278 return mZoneInfoBroker.equals(zoneKey);
288 mZoneInfoStore = zoneInfoStore;
310 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
312 "initForYear(): Year %d outside range [%d, %d]\n",
319 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
320 logging::printf(
"initForYear(): %d\n", year);
325 mTransitionStorage.
init();
333 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
334 logging::printf(
"==== Step 1: findMatches()\n");
336 mNumMatches = findMatches(mZoneInfoBroker, startYm, untilYm, mMatches,
338 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
341 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
342 logging::printf(
"==== Step 2: createTransitions()\n");
344 createTransitions(mTransitionStorage, mMatches, mNumMatches);
345 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
348 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
349 logging::printf(
"==== Step 3: fixTransitionTimes()\n");
351 Transition** begin = mTransitionStorage.getActivePoolBegin();
352 Transition** end = mTransitionStorage.getActivePoolEnd();
353 fixTransitionTimes(begin, end);
354 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
357 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
358 logging::printf(
"==== Step 4: generateStartUntilTimes()\n");
360 generateStartUntilTimes(begin, end);
361 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
364 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
365 logging::printf(
"==== Step 5: calcAbbreviations()\n");
367 calcAbbreviations(begin, end);
368 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
log(); }
387 const typename D::ZoneInfoStore* zoneInfoStore ,
391 mZoneInfoStore(zoneInfoStore)
397 friend class ::ExtendedZoneProcessorTest_compareEraToYearMonth;
398 friend class ::ExtendedZoneProcessorTest_compareEraToYearMonth2;
399 friend class ::ExtendedZoneProcessorTest_createMatchingEra;
400 friend class ::ExtendedZoneProcessorTest_findMatches_simple;
401 friend class ::ExtendedZoneProcessorTest_findMatches_named;
402 friend class ::ExtendedZoneProcessorTest_findCandidateTransitions;
403 friend class ::ExtendedZoneProcessorTest_createTransitionsFromNamedMatch;
404 friend class ::ExtendedZoneProcessorTest_getTransitionTime;
405 friend class ::ExtendedZoneProcessorTest_createTransitionForYear;
406 friend class ::ExtendedZoneProcessorTest_calcInteriorYears;
407 friend class ::ExtendedZoneProcessorTest_getMostRecentPriorYear;
408 friend class ::ExtendedZoneProcessorTest_compareTransitionToMatchFuzzy;
409 friend class ::ExtendedZoneProcessorTest_compareTransitionToMatch;
410 friend class ::ExtendedZoneProcessorTest_processTransitionCompareStatus;
411 friend class ::ExtendedZoneProcessorTest_fixTransitionTimes_generateStartUntilTimes;
412 friend class ::ExtendedZoneProcessorTest_setZoneKey;
413 friend class ::ExtendedTransitionValidation;
414 friend class ::CompleteTransitionValidation;
426 static const uint8_t kMaxMatches = 4;
432 static const uint8_t kMaxInteriorYears = 4;
435 return mZoneInfoBroker.equals(
446 static uint8_t findMatches(
447 const typename D::ZoneInfoBroker& zoneInfo,
448 const extended::YearMonthTuple& startYm,
449 const extended::YearMonthTuple& untilYm,
453 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
454 logging::printf(
"findMatches()\n");
458 for (uint8_t iEra = 0; iEra < zoneInfo.numEras(); iEra++) {
459 const typename D::ZoneEraBroker era = zoneInfo.era(iEra);
460 if (eraOverlapsInterval(prevMatch, era, startYm, untilYm)) {
461 if (iMatch < maxMatches) {
462 matches[iMatch] = createMatchingEra(
463 prevMatch, era, startYm, untilYm);
464 prevMatch = &matches[iMatch];
497 static bool eraOverlapsInterval(
499 const typename D::ZoneEraBroker& era,
500 const extended::YearMonthTuple& startYm,
501 const extended::YearMonthTuple& untilYm) {
502 return (prevMatch ==
nullptr || compareEraToYearMonth(
503 prevMatch->era, untilYm.year, untilYm.month) < 0)
504 && compareEraToYearMonth(era, startYm.year, startYm.month) > 0;
508 static int8_t compareEraToYearMonth(
const typename D::ZoneEraBroker& era,
509 int16_t year, uint8_t month) {
510 if (era.untilYear() < year)
return -1;
511 if (era.untilYear() > year)
return 1;
512 if (era.untilMonth() < month)
return -1;
513 if (era.untilMonth() > month)
return 1;
514 if (era.untilDay() > 1)
return 1;
516 if (era.untilTimeSeconds() > 0)
return 1;
528 const typename D::ZoneEraBroker& era,
529 const extended::YearMonthTuple& startYm,
530 const extended::YearMonthTuple& untilYm) {
534 extended::DateTuple startDate = (prevMatch ==
nullptr)
535 ? extended::DateTuple{
542 : extended::DateTuple{
543 prevMatch->era.untilYear(),
544 prevMatch->era.untilMonth(),
545 prevMatch->era.untilDay(),
546 (int32_t) prevMatch->era.untilTimeSeconds(),
547 prevMatch->era.untilTimeSuffix()
549 extended::DateTuple lowerBound{
556 if (startDate < lowerBound) {
557 startDate = lowerBound;
560 extended::DateTuple untilDate{
564 (int32_t) era.untilTimeSeconds(),
565 era.untilTimeSuffix()
567 extended::DateTuple upperBound{
574 if (upperBound < untilDate) {
575 untilDate = upperBound;
578 return {startDate, untilDate, era, prevMatch, 0, 0};
585 static void createTransitions(
588 uint8_t numMatches) {
589 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
590 logging::printf(
"createTransitions()\n");
593 for (uint8_t i = 0; i < numMatches; i++) {
594 createTransitionsForMatch(transitionStorage, &matches[i]);
599 static void createTransitionsForMatch(
602 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
603 logging::printf(
"== createTransitionsForMatch()\n");
605 const typename D::ZonePolicyBroker policy = match->era.zonePolicy();
606 if (policy.isNull()) {
607 createTransitionsFromSimpleMatch(transitionStorage, match);
609 createTransitionsFromNamedMatch(transitionStorage, match);
614 static void createTransitionsFromSimpleMatch(
617 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
618 logging::printf(
"== createTransitionsFromSimpleMatch()\n");
621 Transition* freeTransition = transitionStorage.getFreeAgent();
622 createTransitionForYear(freeTransition, 0 ,
623 typename D::ZoneRuleBroker() , match);
624 freeTransition->compareStatus = extended::CompareStatus::kExactMatch;
625 match->lastOffsetSeconds = freeTransition->offsetSeconds;
626 match->lastDeltaSeconds = freeTransition->deltaSeconds;
627 transitionStorage.addFreeAgentToActivePool();
628 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
629 transitionStorage.log();
634 static void createTransitionsFromNamedMatch(
637 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
638 logging::printf(
"== createTransitionsFromNamedMatch()\n");
641 transitionStorage.resetCandidatePool();
642 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
643 match->log(); logging::printf(
"\n");
647 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
648 logging::printf(
"---- Pass 1: findCandidateTransitions()\n");
650 findCandidateTransitions(transitionStorage, match);
651 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
652 transitionStorage.log();
657 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
658 logging::printf(
"---- Pass 2: fixTransitionTimes()\n");
661 transitionStorage.getCandidatePoolBegin(),
662 transitionStorage.getCandidatePoolEnd());
666 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
667 logging::printf(
"---- Pass 3: selectActiveTransitions()\n");
669 selectActiveTransitions(
670 transitionStorage.getCandidatePoolBegin(),
671 transitionStorage.getCandidatePoolEnd());
672 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
673 transitionStorage.log();
676 transitionStorage.addActiveCandidatesToActivePool();
677 match->lastOffsetSeconds = lastTransition->offsetSeconds;
678 match->lastDeltaSeconds = lastTransition->deltaSeconds;
679 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
680 transitionStorage.log();
685 static void findCandidateTransitions(
688 using extended::CompareStatus;
690 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
691 logging::printf(
"findCandidateTransitions(): \n");
693 logging::printf(
"\n");
695 const typename D::ZonePolicyBroker policy = match->era.zonePolicy();
696 uint8_t numRules = policy.numRules();
697 int16_t startY = match->startDateTime.year;
698 int16_t endY = match->untilDateTime.year;
703 Transition** prior = transitionStorage.reservePrior();
704 (*prior)->isValidPrior =
false;
705 for (uint8_t r = 0; r < numRules; r++) {
706 const typename D::ZoneRuleBroker rule = policy.rule(r);
709 int16_t interiorYears[kMaxInteriorYears];
710 uint8_t numYears = calcInteriorYears(interiorYears, kMaxInteriorYears,
711 rule.fromYear(), rule.toYear(), startY, endY);
712 for (uint8_t y = 0; y < numYears; y++) {
713 int16_t year = interiorYears[y];
714 Transition* t = transitionStorage.getFreeAgent();
715 createTransitionForYear(t, year, rule, match);
716 CompareStatus status = compareTransitionToMatchFuzzy(t, match);
717 if (status == CompareStatus::kPrior) {
718 transitionStorage.setFreeAgentAsPriorIfValid();
719 }
else if (status == CompareStatus::kWithinMatch) {
720 transitionStorage.addFreeAgentToCandidatePool();
728 int16_t priorYear = getMostRecentPriorYear(
729 rule.fromYear(), rule.toYear(), startY, endY);
731 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
733 "findCandidateTransitions(): priorYear: %d\n", priorYear);
735 Transition* t = transitionStorage.getFreeAgent();
736 createTransitionForYear(t, priorYear, rule, match);
737 transitionStorage.setFreeAgentAsPriorIfValid();
743 if ((*prior)->isValidPrior) {
744 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
746 "findCandidateTransitions(): adding prior to Candidate pool\n");
747 logging::printf(
" ");
749 logging::printf(
"\n");
751 transitionStorage.addPriorToCandidatePool();
774 static uint8_t calcInteriorYears(
775 int16_t* interiorYears,
776 uint8_t maxInteriorYears,
777 int16_t fromYear, int16_t toYear,
778 int16_t startYear, int16_t endYear) {
780 for (int16_t year = startYear; year <= endYear; year++) {
781 if (fromYear <= year && year <= toYear) {
782 interiorYears[i] = year;
784 if (i >= maxInteriorYears)
break;
795 static void createTransitionForYear(
798 const typename D::ZoneRuleBroker& rule,
801 t->offsetSeconds = match->era.offsetSeconds();
802 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
809 t->transitionTime = match->startDateTime;
810 t->deltaSeconds = match->era.deltaSeconds();
813 t->transitionTime = getTransitionTime(year, rule);
814 t->deltaSeconds = rule.deltaSeconds();
815 ace_common::strncpy_T(
816 t->abbrev, rule.letter(), kAbbrevSize - 1);
833 static int16_t getMostRecentPriorYear(
834 int16_t fromYear, int16_t toYear,
835 int16_t startYear, int16_t ) {
837 if (fromYear < startYear) {
838 if (toYear < startYear) {
841 return startYear - 1;
852 static extended::DateTuple getTransitionTime(
853 int16_t year,
const typename D::ZoneRuleBroker& rule) {
855 MonthDay monthDay = calcStartDayOfMonth(
859 rule.onDayOfMonth());
864 (int32_t) rule.atTimeSeconds(),
879 static extended::CompareStatus compareTransitionToMatchFuzzy(
881 return compareDateTupleFuzzy(
883 match->startDateTime,
884 match->untilDateTime);
896 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
897 logging::printf(
"fixTransitionTimes(): START; #transitions=%d\n",
898 (
int) (end - begin));
905 for (
Transition** iter = begin; iter != end; ++iter) {
908 &curr->transitionTime,
911 &curr->transitionTime,
912 &curr->transitionTimeS,
913 &curr->transitionTimeU);
916 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
917 logging::printf(
"fixTransitionTimes(): FIXED\n");
919 logging::printf(
"fixTransitionTimes(): END\n");
928 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
929 logging::printf(
"selectActiveTransitions(): #candidates: %d\n",
930 (
int) (end - begin));
934 for (
Transition** iter = begin; iter != end; ++iter) {
936 processTransitionCompareStatus(transition, &prior);
942 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
944 "selectActiveTransitions(): found latest prior\n");
946 #if ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG
947 prior->originalTransitionTime = prior->transitionTime;
949 prior->transitionTime = prior->match->startDateTime;
959 static void processTransitionCompareStatus(
962 using extended::CompareStatus;
964 CompareStatus status = compareTransitionToMatch(
965 transition, transition->match);
966 transition->compareStatus = status;
968 if (status == CompareStatus::kExactMatch) {
970 (*prior)->compareStatus = CompareStatus::kFarPast;
972 (*prior) = transition;
973 }
else if (status == CompareStatus::kPrior) {
975 if ((*prior)->transitionTimeU <= transition->transitionTimeU) {
976 (*prior)->compareStatus = CompareStatus::kFarPast;
977 (*prior) = transition;
979 transition->compareStatus = CompareStatus::kFarPast;
982 (*prior) = transition;
995 static extended::CompareStatus compareTransitionToMatch(
1000 int32_t prevMatchOffsetSeconds;
1001 int32_t prevMatchDeltaSeconds;
1002 if (match->prevMatch) {
1003 prevMatchOffsetSeconds = match->prevMatch->lastOffsetSeconds;
1004 prevMatchDeltaSeconds = match->prevMatch->lastDeltaSeconds;
1006 prevMatchOffsetSeconds = match->era.offsetSeconds();
1007 prevMatchDeltaSeconds = 0;
1011 extended::DateTuple stw;
1012 extended::DateTuple sts;
1013 extended::DateTuple stu;
1015 &match->startDateTime,
1016 prevMatchOffsetSeconds,
1017 prevMatchDeltaSeconds,
1023 const extended::DateTuple& ttw = transition->transitionTime;
1024 const extended::DateTuple& tts = transition->transitionTimeS;
1025 const extended::DateTuple& ttu = transition->transitionTimeU;
1030 if (ttw == stw || tts == sts || ttu == stu) {
1031 return extended::CompareStatus::kExactMatch;
1035 return extended::CompareStatus::kPrior;
1043 const extended::DateTuple& matchUntil = match->untilDateTime;
1044 const extended::DateTuple* transitionTime;
1046 transitionTime = &tts;
1048 transitionTime = &ttu;
1050 transitionTime = &ttw;
1052 if (*transitionTime < matchUntil) {
1053 return extended::CompareStatus::kWithinMatch;
1055 return extended::CompareStatus::kFarFuture;
1064 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
1066 "generateStartUntilTimes(): #transitions=%d\n",
1067 (
int) (end - begin));
1072 if (begin == end)
return;
1075 bool isAfterFirst =
false;
1077 for (
Transition** iter = begin; iter != end; ++iter) {
1081 const extended::DateTuple& tt = t->transitionTime;
1083 prev->untilDateTime = tt;
1089 int32_t seconds = tt.seconds + (
1090 - prev->offsetSeconds - prev->deltaSeconds
1091 + t->offsetSeconds + t->deltaSeconds);
1092 t->startDateTime = {tt.year, tt.month, tt.day, seconds, tt.suffix};
1093 extended::normalizeDateTuple(&t->startDateTime);
1105 const extended::DateTuple& st = t->startDateTime;
1107 st.seconds - (t->offsetSeconds + t->deltaSeconds);
1109 t->startEpochSeconds = ld.toEpochSeconds() + offsetSeconds;
1112 isAfterFirst =
true;
1116 extended::DateTuple untilTimeW;
1117 extended::DateTuple untilTimeS;
1118 extended::DateTuple untilTimeU;
1120 &prev->match->untilDateTime,
1121 prev->offsetSeconds,
1126 prev->untilDateTime = untilTimeW;
1133 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
1134 logging::printf(
"calcAbbreviations(): #transitions: %d\n",
1135 (
int) (end - begin));
1137 for (
Transition** iter = begin; iter != end; ++iter) {
1139 if (ACE_TIME_EXTENDED_ZONE_PROCESSOR_DEBUG) {
1141 "calcAbbreviations(): format:%s, deltaSeconds:%d, letter:%s\n",
1142 t->format(), t->deltaSeconds, t->abbrev);
1155 const typename D::ZoneInfoStore* mZoneInfoStore;
1156 typename D::ZoneInfoBroker mZoneInfoBroker;
1159 mutable uint8_t mNumMatches = 0;
static int16_t currentEpochYear()
Get the current epoch year.
An implementation of ZoneProcessor that supports for all zones defined by the TZ Database.
void printTargetNameTo(Print &printer) const override
Print the full identifier (e.g.
static const uint8_t kMaxTransitions
Max number of Transitions required for all Zones supported by this class.
FindResult findByEpochSeconds(acetime_t epochSeconds) const override
uint8_t getTransitionAllocSize() const
Get the largest allocation size of TransitionStorage.
extended::TransitionForDateTimeTemplate< D > TransitionForDateTime
Exposed only for testing purposes.
void resetTransitionAllocSize()
Reset the TransitionStorage high water mark.
void printShortNameTo(Print &printer) const override
Print a short human-readable identifier (e.g.
extended::TransitionTemplate< D > Transition
Exposed only for testing purposes.
ExtendedZoneProcessorTemplate(uint8_t type, const typename D::ZoneInfoStore *zoneInfoStore, uintptr_t zoneKey)
Constructor.
bool equalsZoneKey(uintptr_t zoneKey) const override
Return true if ZoneProcessor is associated with the given opaque zoneKey.
extended::MatchingEraTemplate< D > MatchingEra
Exposed only for testing purposes.
bool initForEpochSeconds(acetime_t epochSeconds) const
Initialize using the epochSeconds.
void setZoneKey(uintptr_t zoneKey) override
Set the opaque zoneKey of this object to a new value, reseting any internally cached information.
uint32_t getZoneId() const override
Return the unique stable zoneId.
void printNameTo(Print &printer) const override
Print a human-readable identifier (e.g.
void log() const
Used only for debugging.
extended::TransitionForSecondsTemplate< D > TransitionForSeconds
Exposed only for testing purposes.
extended::TransitionStorageTemplate< kMaxTransitions, D > TransitionStorage
Exposed only for testing purposes.
FindResult findByLocalDateTime(const LocalDateTime &ldt) const override
Return the search results at given LocalDateTime.
void setZoneInfoStore(const typename D::ZoneInfoStore *zoneInfoStore)
Set the zone info store at runtime.
bool initForYear(int16_t year) const
Initialize the zone rules cache, keyed by the "current" year.
bool isLink() const override
Return true if timezone is a Link entry pointing to a Zone entry.
A specific implementation of ExtendedZoneProcessorTemplate that uses the extended::Info::ZoneXxxBroke...
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:
A storage object that creates an ZoneInfoBroker from a key that identifies the ZoneInfo.
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.
uint8_t getAllocSize() const
Return the maximum number of transitions which was allocated.
void resetAllocSize()
Reset the current allocation size.
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 init()
Initialize all pools to 0 size, usually when a new year is initialized.
void log() const
Verify that the indexes are valid.
Identifiers used by implementation code which need to be publically exported.
const uint8_t kAbbrevSize
Size of the c-string buffer needed to hold a time zone abbreviation.
int32_t acetime_t
Type for the number of seconds from epoch.
static const uint8_t kSuffixW
Represents 'w' or wall time.
static const uint8_t kSuffixS
Represents 's' or standard time.
static const uint8_t kSuffixU
Represents 'u' or UTC time.
Representation of a given time zone, implemented as an array of ZoneEra records.
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,...
const TransitionTemplate< D > * curr
The matching transition, or null if not found or in gap.
const TransitionTemplate< D > * prev
The previous transition.
uint8_t num
Number of matches: 0, 1, 2.
Tuple of a matching Transition and its 'fold'.
const TransitionTemplate< D > * curr
The matching transition, or null if not found.
uint8_t num
Number of occurrences of the resulting LocalDateTime: 0, 1, or 2.
uint8_t fold
1 if corresponding datetime occurred the second time
Represents an interval of time where the time zone obeyed a certain UTC offset and DST delta.
int32_t deltaSeconds
The DST delta seconds.
char abbrev[kAbbrevSize]
The calculated effective time zone abbreviation, e.g.
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 standard time offset seconds, not the total offset.
A simple tuple to represent a year/month pair.