tzdb.h
Go to the documentation of this file.
1 /****
2  * tzdb.h - Time Zone database support
3  *
4  * This file is part of the Timezone Library
5  *
6  * This library is free software: you can redistribute it and/or modify it under the terms of the
7  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along with this library.
14  * If not, see <https://www.gnu.org/licenses/>.
15  *
16  ****/
17 
18 #pragma once
19 
20 #include "Timezone.h"
21 #include <FlashString/Array.hpp>
22 #include <FlashString/Vector.hpp>
23 #include <FlashString/Map.hpp>
24 
25 #if TZINFO_WANT_NAME
26 #define TZINFO_FIELD_NAME area,
27 #else
28 #define TZINFO_FIELD_NAME
29 #endif
30 
31 #if TZINFO_WANT_TZSTR
32 #define TZINFO_FIELD_TZSTR tzstr,
33 #else
34 #define TZINFO_FIELD_TZSTR
35 #endif
36 
37 #if TZINFO_WANT_RULES
38 #define TZINFO_FIELD_RULES dst_rule, std_rule,
39 #else
40 #define TZINFO_FIELD_RULES
41 #endif
42 
43 #if TZINFO_WANT_TRANSITIONS
44 #define TZINFO_FIELD_TRANSITIONS tznames, transitions,
45 #else
46 #define TZINFO_FIELD_TRANSITIONS
47 #endif
48 
49 // clang-format off
50 #define DEFINE_REF_LOCAL(name, refname) \
51  static constexpr decltype(refname)& name = refname;
52 
53 #define TZ_DEFINE_RULE_LOCAL(name, ...) \
54  static constexpr const Rule name PROGMEM {__VA_ARGS__};
55 
56 #define TZ_DEFINE_PSTR_LOCAL(name, s) \
57  static constexpr const char* name PROGMEM_PSTR = s;
58 
59 #define TIMEZONE_BEGIN(clsname, area_, location_) \
60  class clsname : public Timezone { \
61  public: \
62  clsname() : Timezone(fromPosix(tzstr)) { } \
63  TZ_DEFINE_PSTR_LOCAL(location, location_)
64 
65 #define TIMEZONE_END() \
66  static constexpr const Info info PROGMEM { \
67  location, \
68  TZINFO_FIELD_NAME \
69  TZINFO_FIELD_TZSTR \
70  TZINFO_FIELD_RULES \
71  TZINFO_FIELD_TRANSITIONS \
72  }; \
73  };
74 // clang-format on
75 
76 namespace TZ
77 {
78 struct Transition {
79  int64_t time : 40;
80  uint8_t desigidx : 8;
81  int16_t offsetMins : 15;
82  bool isdst : 1;
83 
84  operator time_t() const
85  {
86  return time;
87  }
88 
89  time_t local() const
90  {
91  return time + (offsetMins * 60);
92  }
93 };
94 
95 #ifndef __WIN32
96 static_assert(sizeof(Transition) == 8, "Bad Transition def");
97 #endif
98 
99 static constexpr const Rule PROGMEM rule_none{};
100 DEFINE_FSTR_ARRAY_LOCAL(transitions_none, Transition)
101 
102 struct Info {
104 #if TZINFO_WANT_NAME
105  const FSTR::String& area;
106 #endif
107 #if TZINFO_WANT_TZSTR
108  PGM_P tzstr;
109 #endif
110 #if TZINFO_WANT_RULE
111  const Rule& dstStart;
112  const Rule& stdStart;
113 #endif
114 #if TZINFO_WANT_TRANSITIONS
115  PGM_P tznames;
116  const FSTR::Array<Transition>& transitions;
117 #endif
118 
119 #if TZINFO_WANT_NAME
120  String name() const
121  {
122  String s;
123  s += area;
124  s += '/';
125  s += location;
126  return s;
127  }
128 #endif
129 
130  operator Timezone() const
131  {
132 #if TZINFO_WANT_TZSTR
133  return Timezone::fromPosix(tzstr);
134 #elif TZINFO_WANT_RULE
135  return Timezone(dstStart, stdStart);
136 #endif
137  }
138 
139 #if TZINFO_WANT_TRANSITIONS
140  DateTime::ZoneInfo getInfo(const Transition& tt) const
141  {
142  return DateTime::ZoneInfo{
143  .tag = Rule::Tag::fromString(&tznames[tt.desigidx]),
144  .offsetMins = tt.offsetMins,
145  .isDst = tt.isdst,
146  };
147  }
148 #endif
149 
150  explicit operator bool() const
151  {
152  return location;
153  }
154 
155  static const Info& empty();
156 };
157 
160 
162 
163 
176 const Info* findZone(const String& name);
177 
178 } // namespace TZ
#define PROGMEM
Definition: Arch/Esp32/Components/libc/src/include/sys/pgmspace.h:26
#define PGM_P
Definition: Arch/Esp32/Components/libc/src/include/sys/pgmspace.h:30
TZ::Timezone Timezone
Definition: Timezone.h:383
Class to access an array of integral values stored in flash.
Definition: Array.hpp:124
Class template to access an associative map.
Definition: Map.hpp:118
describes a counted string stored in flash memory
Definition: String.hpp:174
Class to access a Vector of objects stored in flash.
Definition: Vector.hpp:110
The String class.
Definition: WString.h:133
static Timezone fromPosix(const char *tzstr)
#define DEFINE_FSTR_ARRAY_LOCAL(name, ElementType,...)
Like DEFINE_FSTR_ARRAY except reference is declared static constexpr.
Definition: Array.hpp:55
#define DECLARE_FSTR_MAP(name, KeyType, ContentType)
Declare a global Map& reference.
Definition: Map.hpp:42
Definition: Timezone.h:33
static constexpr const Rule PROGMEM rule_none
Definition: tzdb.h:99
const Info * findZone(const String &name)
Find a zone given its full name.
static Tag fromString(const char *s)
Basic information required when displaying or handling local times.
Definition: DateTime.h:144
Tag tag
Abbreviation such as "GMT", "EEST" shown after time.
Definition: DateTime.h:166
Definition: tzdb.h:102
static const Info & empty()
PGM_P location
Definition: tzdb.h:103
Describe rules for when daylight/summer time begins, and when standard time begins.
Definition: Timezone.h:124
Definition: tzdb.h:78
bool isdst
Definition: tzdb.h:82
int16_t offsetMins
Definition: tzdb.h:81
uint8_t desigidx
Definition: tzdb.h:80
int64_t time
Definition: tzdb.h:79
time_t local() const
Definition: tzdb.h:89