Skip to content

Commit 3dc2f58

Browse files
authored
Merge pull request #127 from bxparks/develop
merge 4.1.0 into master
2 parents 9599d04 + d894b8f commit 3dc2f58

File tree

16 files changed

+178
-165
lines changed

16 files changed

+178
-165
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Changelog
22

33
- unreleased
4+
- 4.1.0 (2025-11-17, TZDB version 2025b)
5+
- **Breaking** Replace `uint8_t ZonedExtra.type()` with `Resolved
6+
ZonedExtra.resolved()`
7+
- `ZonedExtra::resolved()` has the same behavior and semantics as
8+
`ZonedDateTime.resolved()`
49
- 4.0.0 (2025-10-21, TZDB version 2025b)
510
- See [MIGRATING.md](MIGRATING.md) on breaking API changes, and how to
611
migrate.

MIGRATING.md

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,31 @@
22

33
## Table of Contents
44

5-
* [Migrating to v4.0.0](#MigratingToVersion400)
6-
* [Migrating to v3.0.0](#MigratingToVersion300)
7-
* [Migrating to v2.3.0](#MigratingToVersion220)
8-
* [Migrating to v2.2.0](#MigratingToVersion220)
9-
* [Migrating to v2.1.0](#MigratingToVersion210)
10-
* [Migrating to v2.0.0](#MigratingToVersion200)
11-
* [Migrating to v1.9.0](#MigratingToVersion190)
12-
* [Migrating to v1.8.0](#MigratingToVersion180)
13-
14-
<a name="MigratingToVersion400"></a>
5+
* [Migrating to v4.1.0](#migrating-to-v410)
6+
* [Migrating to v4.0.0](#migrating-to-v400)
7+
* [Migrating to v3.0.0](#migrating-to-v300)
8+
* [Migrating to v2.3.0](#migrating-to-v230)
9+
* [Migrating to v2.2.0](#migrating-to-v220)
10+
* [Migrating to v2.1.0](#migrating-to-v210)
11+
* [Migrating to v2.0.0](#migrating-to-v200)
12+
* [Migrating to v1.9.0](#migrating-to-v190)
13+
* [Migrating to v1.8.0](#migrating-to-v180)
14+
15+
## Migrating to v4.1.0
16+
17+
The `uint8_t ZonedExtra::type()` function is replaced with `Resolved
18+
ZonedExtra::resolved()` which returns an enum of type `Resolved`. The new
19+
function has exactly the same behavior and semantics as
20+
`ZonedDateTime::resolved()` which simplifies the implementation and the usage of
21+
the library.
22+
23+
Here is the mapping from the old values to the new enum:
24+
25+
- `kTypeNotFound` -> `Resolved::kError`
26+
- `kTypeExact` -> `Resolved::kUnique`
27+
- `kTypeGap` -> `Resolved::kGapEarlier` or `Resolved::kGapLater`
28+
- `kTypeOverlap` -> `Resolved::kOverlapEarlier` or `Resolved::kOverlapLater`
29+
1530
## Migrating to v4.0.0
1631

1732
These changes were originally intended for 3.0.0, but I ran out of time, so I
@@ -93,7 +108,6 @@ the `resolved` parameter which is an enum type of `Resolved`. It has 5 options:
93108
If the calling code does not care about how an ambiguity was resolved, then this
94109
parameter can be ignored.
95110

96-
<a name="MigratingToVersion300"></a>
97111
## Migrating to v3.0.0
98112

99113
### Info Container Class
@@ -126,7 +140,6 @@ which may have leaked out is `ace_time::internal::kAbbrevSize` which is the size
126140
of the string buffer needed to hold the longest TimeZone abbreviation (e.g.
127141
"PST"). This constant is now at `ace_time::kAbbrevSize`.
128142

129-
<a name="MigratingToVersion230"></a>
130143
## Migrating to v2.3.0
131144

132145
The internal implementation details of various classes have changed
@@ -210,7 +223,6 @@ we can be confident that all algorithms (`BasicZoneProcessor`,
210223
`zonedbx`, `zonedbc`) in the AceTime library are consistent with these third
211224
party libraries.
212225
213-
<a name="MigratingToVersion220"></a>
214226
## Migrating to v2.2
215227
216228
### Immutable TimeZone class
@@ -250,10 +262,8 @@ TimeZone newTz = TimeZone::forTimeOffset(
250262
ZonedDateTime newDt = zdt.convertToTimeZone(newTz);
251263
```
252264

253-
<a name="MigratingToVersion210"></a>
254265
## Migrating to v2.1
255266

256-
<a name="UnifiedLinks"></a>
257267
### Unified Links
258268

259269
Over the years, I implemented 4 different versions of the Link entries:
@@ -307,7 +317,6 @@ only 2 methods which apply only to Link time zones:
307317
* Prints the name of the target Zone if the current zone is a link.
308318
* It prints nothing is `isLink()` is false.
309319

310-
<a name="ZonedExtra"></a>
311320
### ZonedExtra
312321

313322
The `ZonedExtra` class was created to replace 3 ad-hoc query methods on the
@@ -333,10 +342,8 @@ The `ZonedExtra` object provides access to other meta-information about the time
333342
zone at that particular time. See the [ZonedExtra](USER_GUIDE.md#ZonedExtra)
334343
section in the `USER_GUIDE.md` for more detailed information about this class.
335344

336-
<a name="MigratingToVersion200"></a>
337345
## Migrating to v2.0
338346

339-
<a name="HighLevel200"></a>
340347
### High Level
341348

342349
The primary purpose of AceTime v2 is to extend the range of years supported by
@@ -390,7 +397,6 @@ increase of 2.5-3.5 kiB of flash memory would be negligible on those processors.
390397
Some backwards incompatible changes were necessary from v1 to v2. These are
391398
explained in detail in the next section.
392399

393-
<a name="Details200"></a>
394400
### Details
395401

396402
AceTime v2 implements the following major changes and features:
@@ -491,7 +497,6 @@ number of options:
491497
The next time the device is rebooted, the date and time will use the
492498
new epoch year instead of the old epoch year.
493499

494-
<a name="Motivation200"></a>
495500
### Background Motivation
496501

497502
Using 32-bit integer field for epochSeconds gives a range of about 136 years.
@@ -515,13 +520,11 @@ The updated AceTime v2 is designed to support a 100-year interval from
515520
range needs to extended even further in the future, the "current epoch year" is
516521
made adjustable by the client application.
517522

518-
<a name="MigratingToVersion190"></a>
519523
## Migrating to v1.9.0
520524

521525
The `ZoneManager` hierarchy (containing `ManualZoneManager`, `BasicZoneManager`,
522526
and `ExtendedZoneManager`) was refactored from v1.8.0 to v1.9.0.
523527

524-
<a name="ConfiguringZoneManagers"></a>
525528
### Configuring the Zone Managers
526529

527530
In v1.8, the `ZoneManager` was an abstract interface class with 7 pure virtual
@@ -588,7 +591,6 @@ ExtendedoneManager zoneManager(
588591
zoneProcessorCache);
589592
```
590593

591-
<a name="UsingZoneManagers"></a>
592594
### Using the Zone Managers
593595

594596
In v1.8, the `ZoneManager` was the parent interface class of all polymorphic
@@ -652,7 +654,6 @@ It is assumed that most applications will hard code either the
652654
`BasicZoneManager` or the `ExtendedZoneManager`, and will not need this level
653655
of configuration.
654656

655-
<a name="LinkManagers"></a>
656657
### Link Managers
657658

658659
In v1.8, the `LinkManager` was an interface class with pure virtual methods:
@@ -684,7 +685,6 @@ The `BasicLinkManager` and `ExtendedLinkManager` should be used directly,
684685
instead of through the `LinkManager` interface. Since Link Managers were
685686
introduced only in v1.8, I expect almost no one to be affected by this.
686687

687-
<a name="MigratingToVersion180"></a>
688688
## Migrating to v1.8.0
689689

690690
Three breaking changes were made from v1.7.5 to v1.8.0:
@@ -708,7 +708,6 @@ Three breaking changes were made from v1.7.5 to v1.8.0:
708708
The following subsections show how to migrate client application from
709709
AceTime v1.7.5 to AceTime v1.8.0.
710710

711-
<a name="MigratingToAceTimeClock"></a>
712711
### Migrating to AceTimeClock
713712

714713
For AceTime v1.8.0, the clock classes under the `ace_time::clock` namespace have
@@ -738,7 +737,6 @@ using namespace ace_time;
738737
using namespace ace_time::clock;
739738
```
740739

741-
<a name="MigratingTheDS3231Clock"></a>
742740
### Migrating the DS3231Clock
743741

744742
For AceTime v1.8.0, the `DS3231Clock` class was converted into a template class
@@ -834,7 +832,6 @@ consumption by 1500 bytes on an AVR processor. The flash consumption can be
834832
reduced by 2000 bytes if the "fast" version `SimpleWireFastInterface` is used
835833
instead.
836834
837-
<a name="MigratingToLinkManagers"></a>
838835
### Migrating to LinkManagers
839836
840837
In v1.7.5, [thin links](USER_GUIDE.md#ThinLinks) were activated by adding the

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ epoch of 1970-01-01 is provided through conversion functions of the `time_t`
5353
type. Only the 64-bit version of the `time_t` type is supported to avoid the
5454
[Year 2038 Problem](https://en.wikipedia.org/wiki/Year_2038_problem).
5555

56+
The library does *not* support [leap
57+
seconds](https://en.wikipedia.org/wiki/Leap_second) and ignores them. Instead it
58+
uses [UNIX time](https://en.wikipedia.org/wiki/Unix_time) (aka POSIX time) where
59+
the *POSIX second* is variable in duration compared to the [SI
60+
second](https://en.wikipedia.org/wiki/Second). During a leap second, a POSIX
61+
second is conceptually equal to 2 SI seconds, and the POSIX clock changes from
62+
`23:59:58` to `23:59:59`, then is held for 2 seconds before rolling over to
63+
`00:00:00`. Most real-time clock (RTC) chips do not support leap seconds either,
64+
so the final `23:59:59` second will be held for only one second instead of two,
65+
so a clock using AceTime with such an RTC chip will be off by one second after a
66+
leap second compared to the atomic UTC clock.
67+
5668
The companion library [AceTimeClock](https://github.com/bxparks/AceTimeClock)
5769
provides Clock classes to retrieve the time from more accurate sources, such as
5870
an [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) server, or a
@@ -81,14 +93,14 @@ This library can be an alternative to the Arduino Time
8193
(https://github.com/JChristensen/Timezone) libraries.
8294

8395
**Major Changes in v4.0**: Rename `LocalDate` to `PlainDate`; `LocalTime` to
84-
`PlainTime`; `LocalDateTime` to `PlainDateTime. Backwards compatible macros are
96+
`PlainTime`; `LocalDateTime` to `PlainDateTime`. Backwards compatible macros are
8597
provided, so most existing programs should still compile. See [Migrating to
8698
v4.0](MIGRATING.md#MigratingToVersion400) for more details. Add `zonedb2025` and
8799
`zonedbx2025` databases which contain DST transitions for year >= 2025, which
88100
reduces flash memory size. Replace `fold` parameter with `disambiguate` (input)
89101
and `resolved` (output) parameters.
90102

91-
**Version**: 4.0.0 (2025-10-21, TZDB 2025b) \
103+
**Version**: 4.1.0 (2025-11-17, TZDB 2025b) \
92104
**Changelog**: [CHANGELOG.md](CHANGELOG.md) \
93105
**Migration**: [MIGRATING.md](MIGRATING.md) \
94106
**User Guide**: [USER_GUIDE.md](USER_GUIDE.md)
@@ -509,6 +521,7 @@ until 2200.
509521
- [C++11/14/17 Hinnant date](https://github.com/HowardHinnant/date) library
510522
- [GNU libc time](https://www.gnu.org/software/libc/libc.html) library
511523
- [C# Noda Time](https://nodatime.org) library
524+
- [Python whenever](https://pypi.org/project/whenever/)
512525
- [acetimec](https://github.com/bxparks/acetimec) - C version of AceTime
513526
- [acetimego](https://github.com/bxparks/acetimego) - Go or TinyGo version of
514527
AceTime

USER_GUIDE.md

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ The IANA TZ database is programmatically generated into 5 predefined databases:
1919
ranges, and are designed to work with different `ZoneProcessor` and
2020
`ZoneManager` classes.
2121

22-
**Version**: 4.0.0 (2025-10-21, TZDB 2025b)
22+
**Version**: 4.1.0 (2025-11-17, TZDB 2025b)
2323

2424
**Related Documents**:
2525

@@ -1616,7 +1616,7 @@ class ZonedExtra {
16161616
const char* abbrev);
16171617

16181618
bool isError() const;
1619-
uint8_t type() const;
1619+
Resolved resolved() const;
16201620

16211621
TimeOffset timeOffset() const; // stdOffset + dstOffset
16221622
TimeOffset stdOffset() const;
@@ -1640,9 +1640,10 @@ methods on the `ZonedExtra` class:
16401640
uint8_t hour, uint8_t minute, uint8_t second, const TimeZone& tz,
16411641
Disambiguate disambiguate = Disambiguate::kCompatible)`
16421642
1643-
Often the `ZonedDateTime` will be created first from the epochSeconds, then the
1644-
`ZonedExtra` will be created to access additional information about the time
1645-
zone at that particular epochSeconds (e.g. abbreviation):
1643+
Often the `ZonedDateTime` will be created first using the `forComponents()` or
1644+
`forEpochSeconds()` function, then the `ZonedExtra` will be created to access
1645+
additional information about the time zone at that particular epochSeconds or
1646+
components (e.g. abbreviation):
16461647
16471648
```C++
16481649
ExtendedZoneProcessor zoneProcessor;
@@ -1654,9 +1655,11 @@ ZonedDateTime zdt = ZonedDateTime::forEpochSeconds(epochSeconds, tz);
16541655
ZonedExtra ze = ZonedExtra::forEpochSeconds(epochSeconds, tz);
16551656
```
16561657

1657-
The `ZonedExtra::type()` parameter identifies whether the given time instant
1658-
corresponded to a DST gap, or a DST overlap, or an exact match with no
1659-
duplicates.
1658+
The `ZonedExtra::resolved()` parameter indicates how `forComponents()` function
1659+
resolved a gap or an overlap according to the `disambiguate` parameter. For the
1660+
`forEpochSeconds()` function, the resolved parameter will always be
1661+
`Resolved::kUnique`. If the `ZonedExtra` instance is an error, then `resolved()`
1662+
will return `Resolved::kError`.
16601663

16611664
The `ZonedExtra::stdOffset()` is the standard offset of the timezone at the
16621665
given time instant. For example, for `America/Los_Angeles` this will return
@@ -1683,10 +1686,12 @@ abbreviation is 6 characters long.
16831686

16841687
The `ZonedExtra::reqStdOffset()` and `ZonedExtra::reqDstOffset()` are relevant
16851688
and different from the corresponding `stdOffset()` and `dstOffset()` only if the
1686-
`type()` is `kTypeGap`. This occurs only if the `ZonedExtra::forComponents()`
1687-
factory method is used. The `reqStdOffset()` and `reqDstOffset()` are
1688-
derived from the transition line that is used to select the earlier or later
1689-
`PlainDateTime` instance to `epochSeconds`.
1689+
requested `PlainDateTime` was in a gap. In other words, if the
1690+
`ZonedExtra::resolved()` is `Resolved::kGapBefore` or `Resolved::kGapAfter`.
1691+
This occurs only if the `ZonedExtra::forComponents()` factory method is used.
1692+
The `reqStdOffset()` and `reqDstOffset()` are derived from the transition line
1693+
that is used to select the earlier or later `PlainDateTime` instance to
1694+
`epochSeconds`.
16901695

16911696
The `isError()` method returns true if the given `PlainDateTime` or
16921697
`epochSeconds` represents an error condition.
@@ -2155,10 +2160,11 @@ by JavaScript Temporal and the Python whenever libraries.
21552160

21562161
#### Factory Methods with Disambiguation
21572162

2158-
There are 2 main factory methods on `ZonedDateTime`: `forEpochSeconds()` and
2159-
`forComponents()`. The `disambiguate` parameter applies to only the
2160-
`forComponents()` method. The `forEpochSeconds()` function always corresponds to
2161-
a unique `ZonedDateTime` object and does not need a `disambiguate` argument.
2163+
The `ZonedDateTime` and `ZonedExtra` classes have 2 factory methods:
2164+
`forEpochSeconds()` and `forComponents()`. The `disambiguate` parameter applies
2165+
to only the `forComponents()` method. The `forEpochSeconds()` function always
2166+
corresponds to a unique `ZonedDateTime` object and does not need a
2167+
`disambiguate` argument.
21622168

21632169
The `disambiguate` parameter is an enum type that takes 4 values:
21642170

@@ -2178,12 +2184,14 @@ then the `disambiguate` parameter has no effect, because it maps to a unique
21782184

21792185
#### Resolved Disambiguation
21802186

2181-
When the `forComponents()` method returns a `ZonedDateTime`, it is sometimes
2182-
useful to know how the `disambiguate` parameter selected the result. The
2183-
`ZonedDateTime` object exposes a `ZonedDateTime::resolved()` variable. It
2184-
takes 5 values:
2187+
The `ZonedDateTime::forComponents()` method and the
2188+
`ZonedExtra::forComponents()` functions accept the `disambiguate` parameter to
2189+
control what happens during a gap or an overlap. The resulting `ZonedDateTime`
2190+
or `ZonedExtra` exposes a `resolved()` function that returns an enum of type
2191+
`Resolved` which takes 6 values:
21852192

2186-
- `Resolved::kUnique` - the ZonedDateTime is unique
2193+
- `Resolved::kError` - the result was not found or an error occurred
2194+
- `Resolved::kUnique` - the ZonedDateTime or ZonedExtra is unique
21872195
- `Resolved::kOverlapEarlier` - the earlier time in an overlap was selected
21882196
- `Resolved::kOverlapLater` - the later time in an overlap was selected
21892197
- `Resolved::kGapEarlier` - the earlier time in a gap was selected

docs/README.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
11
# Documentation
22

3-
* The `html` directory contains the programmatically generated
4-
[Doxygen docs](https://bxparks.github.io/AceTime/html/) which are viewable on
5-
GitHub Pages.
6-
* The other files are various subsections of the User Guide which are linked
7-
from the main [README.md](../README.md).
3+
The main [README.md](../README.md) and [USER_GUIDE.md](../USER_GUIDE.md)
4+
contain the majority of the documentation.
5+
6+
This directory contains scripts to generate [doxygen](https://www.doxygen.nl/)
7+
documentation from the embedded docstrings in the code.
8+
9+
First, install doxygen and GNU Make if you don't already have them, with
10+
something like the following on an Ubuntu Linux machine:
11+
12+
```
13+
$ sudo apt install doxygen make
14+
```
15+
16+
Second, run the `make` command to generate the HTML files under the `html`
17+
directory:
18+
19+
```
20+
$ cd docs
21+
$ make
22+
```
23+
24+
Third, open the `./docs/html/index.html` file in your web browser.

docs/doxygen.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ PROJECT_NAME = AceTime
3838
# could be handy for archiving the generated documentation or if some version
3939
# control system is used.
4040

41-
PROJECT_NUMBER = 3.0.0
41+
PROJECT_NUMBER = 4.1.0
4242

4343
# Using the PROJECT_BRIEF tag one can provide an optional one line description
4444
# for a project that appears at the top of each page and should give viewer a

examples/AutoBenchmark/Benchmark.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ void disableOptimization(uint32_t value) {
127127
}
128128

129129
void disableOptimization(const ZonedExtra& extra) {
130-
guard ^= extra.type() & 0xff;
130+
guard ^= (uint8_t)extra.resolved() & 0xff;
131131
guard ^= extra.timeOffset().toMinutes() & 0xff;
132132
guard ^= *extra.abbrev();
133133
}

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=AceTime
2-
version=4.0.0
2+
version=4.1.0
33
author=Brian T. Park <[email protected]>
44
maintainer=Brian T. Park <[email protected]>
55
sentence=Date, time, timezone classes for Arduino supporting the full IANA TZ Database to convert epoch seconds to date and time components in different time zones.

src/AceTime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
#include "zonedbc/zone_registry.h"
7878

7979
// Version format: xxyyzz == "xx.yy.zz"
80-
#define ACE_TIME_VERSION 40000
81-
#define ACE_TIME_VERSION_STRING "4.0.0"
80+
#define ACE_TIME_VERSION 40100
81+
#define ACE_TIME_VERSION_STRING "4.1.0"
8282

8383
#endif

0 commit comments

Comments
 (0)