Timezone.h
Go to the documentation of this file.
1 /****
2  * Timezone.h - Time Zone support library
3  *
4  * Original code (c) Jack Christensen Mar 2012
5  * Arduino Timezone Library Copyright (C) 2018 by Jack Christensen and
6  * licensed under GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
7  *
8  * This file is part of the Timezone Library
9  *
10  * This library is free software: you can redistribute it and/or modify it under the terms of the
11  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  * See the GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along with this library.
18  * If not, see <https://www.gnu.org/licenses/>.
19  *
20  * @author mikee47 <mike@sillyhouse.net>
21  * July 2018 Ported to Sming
22  * May 2024 Added Posix TZ string and IANA database support
23  *
24  ****/
25 
26 #pragma once
27 
28 #include <ZonedTime.h>
29 #include <Print.h>
30 #include <limits>
31 
32 namespace TZ
33 {
37 enum week_t {
43 };
44 
48 enum dow_t {
49  Sun = 0,
50  Mon,
51  Tue,
52  Wed,
53  Thu,
54  Fri,
55  Sat,
56 };
57 
61 enum month_t {
62  Jan = 0,
63  Feb,
64  Mar,
65  Apr,
66  May,
67  Jun,
68  Jul,
69  Aug,
70  Sep,
71  Oct,
72  Nov,
73  Dec,
74 };
75 
83 static constexpr time_t minTime = std::max(-5364662400LL, (long long)std::numeric_limits<time_t>::min() + 1);
84 
92 static constexpr time_t maxTime = std::min(253402300799LL, (long long)std::numeric_limits<time_t>::max() - 1);
93 
97 static constexpr time_t invalidTime = maxTime + 1;
98 
124 struct Rule {
125  struct Time {
126  int16_t minutes;
127 
128  constexpr Time(float hours = 0) : minutes(hours * MINS_PER_HOUR)
129  {
130  }
131  };
132 
136  dow_t dow : 4;
139  int16_t offsetMins;
140 
141  int offsetSecs() const
142  {
143  return int(offsetMins) * SECS_PER_MIN;
144  }
145 
151  time_t operator()(unsigned year) const;
152 
156  explicit operator int() const
157  {
158  return (month << 6) | (week << 3) | dow;
159  }
160 
161  bool operator==(const Rule& other) const
162  {
163  return this == &other || memcmp(this, &other, sizeof(other)) == 0;
164  }
165 
166  bool operator!=(const Rule& other) const
167  {
168  return !operator==(other);
169  }
170 
171  static const Rule UTC;
172 };
173 
174 #ifndef __WIN32
175 static_assert(sizeof(Rule) == 12, "Rule size unexpected");
176 #endif
177 
181 class Timezone
182 {
183 public:
185  {
186  }
187 
194  Timezone(const Rule& dstStart, const Rule& stdStart)
195  : dstRule(dstStart), stdRule(stdStart), hasDst(dstRule.tag[0] && dstRule != stdRule)
196  {
197  }
198 
204  explicit Timezone(const Rule& std) : dstRule(std), stdRule(std), hasDst(false)
205  {
206  }
207 
211  void init(const Rule& dstStart, const Rule& stdStart) SMING_DEPRECATED
212  {
213  *this = Timezone(dstStart, stdStart);
214  }
215 
220  static Timezone fromPosix(const char* tzstr);
221 
222  static Timezone fromPosix(const String& tzstr)
223  {
224  return fromPosix(tzstr.c_str());
225  }
228  explicit operator bool() const
229  {
230  return *stdRule.tag != '\0';
231  }
232 
239  time_t toLocal(time_t utc, const Rule** rule = nullptr);
240 
249  ZonedTime makeZoned(time_t utc, bool beforeTransition = false);
250 
279  ZonedTime toUTC(time_t local);
280 
286  bool utcIsDST(time_t utc);
287 
293  bool locIsDST(time_t local);
294 
300  const char* timeTag(bool isDst) const
301  {
302  return isDst ? dstRule.tag : stdRule.tag;
303  }
304 
310  const char* utcTimeTag(time_t utc)
311  {
312  return timeTag(utcIsDST(utc));
313  }
314 
320  const char* localTimeTag(time_t local)
321  {
322  return timeTag(locIsDST(local));
323  }
324 
331  ZonedTime getNextChange(time_t utcFrom);
332 
340  ZonedTime getTransition(uint16_t year, bool toDst);
341 
347  const Rule& getRule(bool isDst) const
348  {
349  return isDst ? dstRule : stdRule;
350  }
351 
355  bool hasDaylightSavings() const
356  {
357  return hasDst;
358  }
359 
360  String toString() const;
361 
362  size_t printTo(Print& p) const;
363 
364 private:
365  /*
366  * Calculate the DST and standard time change points for the given
367  * given year as local and UTC time_t values.
368  */
369  void calcTimeChanges(unsigned yr);
370 
371 private:
372  Rule dstRule{};
373  Rule stdRule{};
374  time_t dstStartUTC{invalidTime};
375  time_t stdStartUTC{invalidTime};
376  bool hasDst{};
377 };
378 
379 } // namespace TZ
380 
382 
String toString(TZ::week_t week)
TZ::Timezone Timezone
Definition: Timezone.h:383
Provides formatted output to stream.
Definition: Print.h:37
The String class.
Definition: WString.h:133
const char * c_str() const
Get a constant (un-modifiable) pointer to String content.
Definition: WString.h:609
Class to support local/UTC time conversions using rules.
Definition: Timezone.h:182
time_t toLocal(time_t utc, const Rule **rule=nullptr)
Convert the given UTC time to local time, standard or daylight time.
ZonedTime getTransition(uint16_t year, bool toDst)
Get transition time for the given year.
size_t printTo(Print &p) const
String toString() const
bool locIsDST(time_t local)
Determine whether the given local time is within the DST interval or the Standard time interval.
ZonedTime makeZoned(time_t utc, bool beforeTransition=false)
Obtain a ZonedTime instance for the given UTC.
bool utcIsDST(time_t utc)
Determine whether the UTC time is within the DST interval or the Standard time interval.
Timezone()
Definition: Timezone.h:184
Timezone(const Rule &dstStart, const Rule &stdStart)
Create a timezone with daylight savings.
Definition: Timezone.h:194
const char * utcTimeTag(time_t utc)
Return the appropriate time tag for a UTC time.
Definition: Timezone.h:310
bool hasDaylightSavings() const
If dst and std rules are the same we do not use daylight savings.
Definition: Timezone.h:355
ZonedTime toUTC(time_t local)
Convert the given local time to UTC time.
ZonedTime getNextChange(time_t utcFrom)
Determine when the next change to/from DST is.
static Timezone fromPosix(const char *tzstr)
void init(const Rule &dstStart, const Rule &stdStart)
Definition: Timezone.h:211
Timezone(const Rule &std)
Create a timezone which has no daylight savings.
Definition: Timezone.h:204
const Rule & getRule(bool isDst) const
Get reference to a timechange rule.
Definition: Timezone.h:347
static Timezone fromPosix(const String &tzstr)
Definition: Timezone.h:222
const char * timeTag(bool isDst) const
Return the appropriate dalight-savings tag to append to displayed times.
Definition: Timezone.h:300
const char * localTimeTag(time_t local)
Return the appropriate time tag for a local time.
Definition: Timezone.h:320
A timestamp representing a UTC 'point in time' associated with a specific timezone.
Definition: ZonedTime.h:25
#define MINS_PER_HOUR
Definition: DateTime.h:28
#define SECS_PER_MIN
Definition: DateTime.h:25
Definition: Timezone.h:33
week_t
Week number for Rule
Definition: Timezone.h:37
@ Third
Definition: Timezone.h:40
@ Fourth
Definition: Timezone.h:41
@ Last
Definition: Timezone.h:42
@ First
Definition: Timezone.h:38
@ Second
Definition: Timezone.h:39
month_t
Month by name. Same as DateTime dtMonth_t.
Definition: Timezone.h:61
@ Jul
Definition: Timezone.h:68
@ Apr
Definition: Timezone.h:65
@ Oct
Definition: Timezone.h:71
@ Feb
Definition: Timezone.h:63
@ Mar
Definition: Timezone.h:64
@ Aug
Definition: Timezone.h:69
@ Nov
Definition: Timezone.h:72
@ May
Definition: Timezone.h:66
@ Jan
Definition: Timezone.h:62
@ Sep
Definition: Timezone.h:70
@ Dec
Definition: Timezone.h:73
@ Jun
Definition: Timezone.h:67
dow_t
Day of week. Same as DateTime dtDays_t.
Definition: Timezone.h:48
@ Mon
Definition: Timezone.h:50
@ Tue
Definition: Timezone.h:51
@ Wed
Definition: Timezone.h:52
@ Sat
Definition: Timezone.h:55
@ Sun
Definition: Timezone.h:49
@ Thu
Definition: Timezone.h:53
@ Fri
Definition: Timezone.h:54
static constexpr time_t maxTime
Largest future timestamp value we could reasonably want.
Definition: Timezone.h:92
static constexpr time_t invalidTime
Value outside normal range used to indicate abnormal or uninitialised time values.
Definition: Timezone.h:97
static constexpr time_t minTime
Earliest timestamp we might wish to use.
Definition: Timezone.h:83
#define SMING_DEPRECATED
Definition: sming_attr.h:37
Type for timezone abbreviation such as "GMT", "EEST".
Definition: DateTime.h:148
Definition: Timezone.h:125
int16_t minutes
Definition: Timezone.h:126
constexpr Time(float hours=0)
Definition: Timezone.h:128
Describe rules for when daylight/summer time begins, and when standard time begins.
Definition: Timezone.h:124
static const Rule UTC
Definition: Timezone.h:171
Time time
Definition: Timezone.h:138
int16_t offsetMins
Offset from UTC.
Definition: Timezone.h:139
bool operator==(const Rule &other) const
Definition: Timezone.h:161
Tag tag
e.g. DST, UTC, etc.
Definition: Timezone.h:134
bool operator!=(const Rule &other) const
Definition: Timezone.h:166
int offsetSecs() const
Definition: Timezone.h:141
week_t week
Definition: Timezone.h:135
month_t month
Definition: Timezone.h:137
time_t operator()(unsigned year) const
Convert the given time change rule to a time_t value for the given year.
dow_t dow
Definition: Timezone.h:136