AceTime  2.3.0
Date and time classes for Arduino that support timezones from the TZ Database.
ZoneSorterByOffsetAndName.h
1 /*
2  * MIT License
3  * Copyright (c) 2021 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_ZONE_SORTER_BY_OFFSET_AND_NAME_H
7 #define ACE_TIME_ZONE_SORTER_BY_OFFSET_AND_NAME_H
8 
9 #include <AceSorting.h>
10 #include "ZoneManager.h"
11 
12 namespace ace_time {
13 
21 template <typename ZM>
23  public:
28  ZoneSorterByOffsetAndName(const ZM& zoneManager) :
29  mZoneManager(zoneManager)
30  {}
31 
36  void fillIndexes(uint16_t indexes[], uint16_t size) const {
37  for (uint16_t i = 0; i < size; i++) {
38  indexes[i] = i;
39  }
40  }
41 
43  void sortIndexes(uint16_t indexes[], uint16_t size) const {
44  ace_sorting::shellSortKnuth(indexes, size,
45  [this](uint16_t indexA, uint16_t indexB) -> bool {
46  auto za = this->mZoneManager.getZoneForIndex(indexA);
47  auto zb = this->mZoneManager.getZoneForIndex(indexB);
48  return this->compareZone(za, zb) < 0;
49  }
50  );
51  }
52 
54  void sortIds(uint32_t ids[], uint16_t size) const {
55  ace_sorting::shellSortKnuth(ids, size,
56  [this](uint32_t a, uint32_t b) -> bool {
57  uint16_t indexA = this->mZoneManager.indexForZoneId(a);
58  uint16_t indexB = this->mZoneManager.indexForZoneId(b);
59  auto za = this->mZoneManager.getZoneForIndex(indexA);
60  auto zb = this->mZoneManager.getZoneForIndex(indexB);
61  return this->compareZone(za, zb) < 0;
62  }
63  );
64  }
65 
67  void sortNames(const char* names[], uint16_t size) const {
68  ace_sorting::shellSortKnuth(names, size,
69  [this](const char* a, const char* b) -> bool {
70  uint16_t indexA = this->mZoneManager.indexForZoneName(a);
71  uint16_t indexB = this->mZoneManager.indexForZoneName(b);
72  auto za = this->mZoneManager.getZoneForIndex(indexA);
73  auto zb = this->mZoneManager.getZoneForIndex(indexB);
74  return this->compareZone(za, zb) < 0;
75  }
76  );
77  }
78 
88  template <typename Z>
89  static int compareZone(const Z& a, const Z& b) {
90  if (a.isNull()) {
91  if (b.isNull()) {
92  return 0;
93  } else {
94  return -1;
95  }
96  }
97  if (b.isNull()) return 1;
98 
99  TimeOffset offsetA = a.stdOffset();
100  TimeOffset offsetB = b.stdOffset();
101  if (offsetA.toSeconds() < offsetB.toSeconds()) return -1;
102  if (offsetA.toSeconds() > offsetB.toSeconds()) return 1;
103  return a.kname().compareTo(b.kname());
104  }
105 
106  private:
107  // disable copy constructor and assignment operator
110  = delete;
111 
112  private:
113  const ZM& mZoneManager;
114 };
115 
116 }
117 
118 #endif
A thin wrapper that represents a time offset from a reference point, usually 00:00 at UTC,...
Definition: TimeOffset.h:56
int32_t toSeconds() const
Return the time offset as seconds.
Definition: TimeOffset.h:131
ZoneSorterByOffsetAndName, templatized on BasicZoneManager or ExtendedZoneManager.
void sortIndexes(uint16_t indexes[], uint16_t size) const
Sort the given array of indexes by UTC offset, then by name.
static int compareZone(const Z &a, const Z &b)
Return <0, 0, or >0 depending on whether Zone a is <, ==, or > than Zone b.
void fillIndexes(uint16_t indexes[], uint16_t size) const
Fill the given array of indexes with index from [0, size).
void sortIds(uint32_t ids[], uint16_t size) const
Sort the given array of zone ids by UTC offset, then by name.
ZoneSorterByOffsetAndName(const ZM &zoneManager)
Constructor.
void sortNames(const char *names[], uint16_t size) const
Sort the given array of zone names by UTC offset, then by name.