Skip to content

Commit 2e4f063

Browse files
committed
Update to v3.0.0 from AceTimeSuite
1 parent 71c49e5 commit 2e4f063

File tree

125 files changed

+8505
-8842
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+8505
-8842
lines changed

CHANGELOG.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
# Changelog
22

3-
- 3.0.0 (2025-01-28, TZDB 2025a)
4-
- merge various AceTime projects into single AceTimeSuite repo
3+
- unreleased
4+
- 3.0.0 (2025-04-25, TZDB version 2025b)
55
- [upgrade to TZDB 2025a](https://lists.iana.org/hyperkitty/list/[email protected]/thread/MWII7R3HMCEDNUCIYQKSSTYYR7UWK4OQ/)
66
- Paraguay adopts permanent -03 starting spring 2024.
77
- Improve pre-1991 data for the Philippines.
88
- Etc/Unknown is now reserved.
9+
- [upgrade to TZDB 2025b](https://lists.iana.org/hyperkitty/list/[email protected]/thread/6JVHNHLB6I2WAYTQ75L6KEPEQHFXAJK3/)
10+
- New zone for Aysén Region in Chile which moves from -04/-03 to -03.
11+
(Creates new zone named America/Coyhaique)
12+
- **breaking** add ZoneInfo data classes and their brokers into `Info`
13+
container class
14+
- allows selection of parallel class hierarchies using the `Info`
15+
container class
16+
- `basic::ZoneInfo` class moves to `basic::Info::ZoneInfo`
17+
- `extended::ZoneInfo` class moves to `extended::Info::ZoneInfo`
18+
- `complete::ZoneInfo` class moves to `complete::Info::ZoneInfo`
19+
- **breaking** move `daysUntil(LocalDate, month, day)` to
20+
`LocalDate::daysUntil(month, day)` for simplicity
21+
- See [Migrating to v3.0](MIGRATING.md#MigratingToVersion300) for more
22+
details.
923
- 2.4.0 (2024-12-13, TZDB version 2024b)
1024
- Support new `%z` value in FORMAT column.
1125
- Upgrade TZDB to 2024b

MIGRATING.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Table of Contents
44

5+
* [Migrating to v3.0.0](#MigratingToVersion300)
56
* [Migrating to v2.3.0](#MigratingToVersion220)
67
* [Migrating to v2.2.0](#MigratingToVersion220)
78
* [Migrating to v2.1.0](#MigratingToVersion210)
@@ -20,6 +21,39 @@
2021
* [Migrating the DS3231Clock](#MigratingTheDS3231Clock)
2122
* [Migrating to LinkManagers](#MigratingToLinkManagers)
2223

24+
<a name="MigratingToVersion300"></a>
25+
## Migrating to v3.0.0
26+
27+
### Info Container Class
28+
29+
The various `ZoneInfo` classes are now nested inside an `Info` container class.
30+
This greatly simplifies the maintenance of the code. But it introduces a small
31+
breaking change. Instead of
32+
33+
```C++
34+
const basic::ZoneInfo*`
35+
const extended::ZoneInfo*`
36+
const complete::ZoneInfo*`
37+
```
38+
we need to use
39+
40+
```C++
41+
const basic::Info::ZoneInfo*`
42+
const extended::Info::ZoneInfo*`
43+
const complete::Info::ZoneInfo*`
44+
```
45+
46+
### Remove 'internal' Namespace
47+
48+
The `ace_time::internal` namespace has been removed and all of its classes and
49+
symbols have been lifted into the `ace_time` namespace. This makes the code
50+
easier to understand and maintain.
51+
52+
Being "internal", most of the objects were not documented. However, one symbol
53+
which may have leaked out is `ace_time::internal::kAbbrevSize` which is the size
54+
of the string buffer needed to hold the longest TimeZone abbreviation (e.g.
55+
"PST"). This constant is now at `ace_time::kAbbrevSize`.
56+
2357
<a name="MigratingToVersion230"></a>
2458
## Migrating to v2.3.0
2559

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
clean:
2+
make -C examples clean
3+
make -C tests clean

README.md

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

33
[![AUnit Tests](https://github.com/bxparks/AceTime/actions/workflows/aunit_tests.yml/badge.svg)](https://github.com/bxparks/AceTime/actions/workflows/aunit_tests.yml)
4-
[![Validation Tests](https://github.com/bxparks/AceTime/actions/workflows/validation.yml/badge.svg)](https://github.com/bxparks/AceTime/actions/workflows/validation.yml)
54

65
The AceTime library provides Date, Time, and TimeZone classes which can convert
76
"epoch seconds" from the AceTime Epoch (default 2050-01-01 UTC) to
@@ -76,7 +75,7 @@ and the `zonedbc` database to support all timezones, for all transitions defined
7675
in the IANA TZ database (`[1844,2087]`), and extending the validity of timezone
7776
calculations from `[2000,10000)` to `[0001,10000)`.
7877

79-
**Version**: 3.0.0 (2025-01-28, TZDB 2025a)
78+
**Version**: 3.0.0 (2025-04-25, TZDB 2025b)
8079

8180
**Changelog**: [CHANGELOG.md](CHANGELOG.md)
8281

@@ -164,13 +163,13 @@ The source files are organized as follows:
164163
* zone databases
165164
* `src/zonedb/` - files generated from TZ Database for
166165
`BasicZoneProcessor` (`ace_time::zonedb` namespace)
167-
* `src/zonedbtesting/` - limited subset of `zonedb` for unit tests
168166
* `src/zonedbx/` - files generated from TZ Database for
169167
`ExtendedZoneProcessor` (`ace_time::zonedbx` namespace)
170-
* `src/zonedbxtesting/` - limited subset of `zonedbx` for unit tests
171168
* `src/zonedbc/` - files generated from TZ Database for
172169
`CompleteZoneProcessor` (`ace_time::zonedbc` namespace)
173-
* `src/zonedbctesting/` - limited subset of `zonedbc` for unit tests
170+
* `src/testingzonedb/` - limited subset of `zonedb` for unit tests
171+
* `src/testingzonedbx/` - limited subset of `zonedbx` for unit tests
172+
* `src/testingzonedbc/` - limited subset of `zonedbc` for unit tests
174173
* `tests/
175174
* unit tests using [AUnit](https://github.com/bxparks/AUnit)
176175
* `examples/` - example programs and benchmarks

USER_GUIDE.md

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The IANA TZ database is programmatically generated into 3 predefined databases:
1818
databases have different accuracy ranges, and are designed to work with
1919
different `ZoneProcessor` and `ZoneManager` classes.
2020

21-
**Version**: 3.0.0 (2025-01-28, TZDB 2025a)
21+
**Version**: 3.0.0 (2025-04-25, TZDB 2025b)
2222

2323
**Related Documents**:
2424

@@ -235,17 +235,17 @@ information are defined in the following namespaces. They are not expected to be
235235
used by application developers under normal circumstances, so these are listed
236236
here for reference:
237237

238-
* `ace_time::basic::ZoneXxx`
239-
* `ace_time::extended::ZoneXxx`
240-
* `ace_time::complete::ZoneXxx`
238+
* `ace_time::basic::Info::ZoneXxx`
239+
* `ace_time::extended::Info::ZoneXxx`
240+
* `ace_time::complete::Info::ZoneXxx`
241241

242-
The `basic::ZoneInfo` and `extended::ZoneInfo` classes (and their associated
243-
`ZoneProcessor` classes) have a resolution of 1 minute, which is sufficient to
244-
represent all UTC offsets and DST shifts of all timezones after 1972
245-
(Africa/Monrovia seems like the last timezone to conform to a one-minute
246-
resolution on Jan 7, 1972). The `complete::ZoneInfo` classes have a resolution
247-
of 1 second, which allows them to represent all timezones, for all years in the
248-
TZ database, over the years `[0001,10000)`.
242+
The `basic::Info::ZoneInfo` and `extended::Info::ZoneInfo` classes (and their
243+
associated `ZoneProcessor` classes) have a resolution of 1 minute, which is
244+
sufficient to represent all UTC offsets and DST shifts of all timezones after
245+
1972 (Africa/Monrovia seems like the last timezone to conform to a one-minute
246+
resolution on Jan 7, 1972). The `complete::Info::ZoneInfo` classes have a
247+
resolution of 1 second, which allows them to represent all timezones, for all
248+
years in the TZ database, over the years `[0001,10000)`.
249249

250250
It is expected that most applications using AceTime will use only a small number
251251
of timezones at the same time (1 to 4 zones have been extensively tested) and
@@ -982,15 +982,15 @@ class TimeZone {
982982
int8_t dstMinute = 0);
983983

984984
static TimeZone forZoneInfo(
985-
const basic::ZoneInfo* zoneInfo,
985+
const basic::Info::ZoneInfo* zoneInfo,
986986
BasicZoneProcessor* zoneProcessor);
987987

988988
static TimeZone forZoneInfo(
989-
const extended::ZoneInfo* zoneInfo,
989+
const extended::Info::ZoneInfo* zoneInfo,
990990
ExtendedZoneProcessor* zoneProcessor);
991991

992992
static TimeZone forZoneInfo(
993-
const complete::ZoneInfo* zoneInfo,
993+
const complete::Info::ZoneInfo* zoneInfo,
994994
CompleteZoneProcessor* zoneProcessor);
995995

996996
static TimeZone forUtc();
@@ -1200,7 +1200,7 @@ void someFunction() {
12001200
#### Extended TimeZone (kTypeExtended)
12011201

12021202
This TimeZone is created using two objects:
1203-
* the `extended::ZoneInfo` data objects contained in
1203+
* the `extended::Info::ZoneInfo` data objects contained in
12041204
[zonedbx/zone_infos.h](src/zonedbx/zone_infos.h)
12051205
* an external instance of `ExtendedZoneProcessor` needed for calculating zone
12061206
transitions
@@ -1651,7 +1651,8 @@ methods on the `ZonedExtra` class:
16511651
uint8_t fold = 0)`
16521652
16531653
Often the `ZonedDateTime` will be created first from the epochSeconds, then the
1654-
`ZonedExtra` will be created to access additional information about the time zone at that particular epochSeconds (e.g. abbreviation):
1654+
`ZonedExtra` will be created to access additional information about the time
1655+
zone at that particular epochSeconds (e.g. abbreviation):
16551656
16561657
```C++
16571658
ExtendedZoneProcessor zoneProcessor;
@@ -1741,7 +1742,7 @@ class BasicZoneManager {
17411742
public:
17421743
BasicZoneManager(
17431744
uint16_t registrySize,
1744-
const basic::ZoneInfo* const* zoneRegistry,
1745+
const basic::Info::ZoneInfo* const* zoneRegistry,
17451746
BasicZoneProcessorCacheBase& zoneProcessorCache
17461747
);
17471748

@@ -1751,7 +1752,7 @@ class BasicZoneManager {
17511752
TimeZone createForZoneId(uint32_t id);
17521753
TimeZone createForZoneIndex(uint16_t index);
17531754
TimeZone createForTimeZoneData(const TimeZoneData& d);
1754-
TimeZone createForZoneInfo(const basic::ZoneInfo* zoneInfo);
1755+
TimeZone createForZoneInfo(const basic::Info::ZoneInfo* zoneInfo);
17551756

17561757
uint16_t indexForZoneName(const char* name) const;
17571758
uint16_t indexForZoneId(uint32_t id) const;
@@ -1764,17 +1765,17 @@ class ExtendedZoneManager {
17641765
public:
17651766
ExtendedZoneManager(
17661767
uint16_t registrySize,
1767-
const extended::ZoneInfo* const* zoneRegistry,
1768+
const extended::Info::ZoneInfo* const* zoneRegistry,
17681769
ExtendedZoneProcessorCacheBase& zoneProcessorCache
17691770
);
17701771

17711772
uint16_t zoneRegistrySize() const;
17721773

1773-
TimeZone createForZoneInfo(const extended::ZoneInfo* zoneInfo);
1774+
TimeZone createForZoneInfo(const extended::Info::ZoneInfo* zoneInfo);
17741775
TimeZone createForZoneId(uint32_t id);
17751776
TimeZone createForZoneIndex(uint16_t index);
17761777
TimeZone createForTimeZoneData(const TimeZoneData& d);
1777-
TimeZone createForZoneInfo(const extended::ZoneInfo* zoneInfo);
1778+
TimeZone createForZoneInfo(const extended::Info::ZoneInfo* zoneInfo);
17781779

17791780
uint16_t indexForZoneName(const char* name) const;
17801781
uint16_t indexForZoneId(uint32_t id) const;
@@ -1787,17 +1788,17 @@ class CompleteZoneManager {
17871788
public:
17881789
CompleteZoneManager(
17891790
uint16_t registrySize,
1790-
const extended::ZoneInfo* const* zoneRegistry,
1791+
const extended::Info::ZoneInfo* const* zoneRegistry,
17911792
CompleteZoneProcessorCacheBase& zoneProcessorCache
17921793
);
17931794

17941795
uint16_t zoneRegistrySize() const;
17951796

1796-
TimeZone createForZoneInfo(const extended::ZoneInfo* zoneInfo);
1797+
TimeZone createForZoneInfo(const extended::Info::ZoneInfo* zoneInfo);
17971798
TimeZone createForZoneId(uint32_t id);
17981799
TimeZone createForZoneIndex(uint16_t index);
17991800
TimeZone createForTimeZoneData(const TimeZoneData& d);
1800-
TimeZone createForZoneInfo(const extended::ZoneInfo* zoneInfo);
1801+
TimeZone createForZoneInfo(const extended::Info::ZoneInfo* zoneInfo);
18011802

18021803
uint16_t indexForZoneName(const char* name) const;
18031804
uint16_t indexForZoneId(uint32_t id) const;
@@ -2022,11 +2023,11 @@ Another useful feature of `ZoneManager::createForZoneId()` over
20222023
`ZoneManager` interface. In contrast, there are 2 different versions of
20232024
`createForZoneInfo()` which live in the corresponding ZoneManager implementation
20242025
classes because each version needs a different `ZoneInfo` type
2025-
(`basic::ZoneInfo` and `extended::ZoneInfo`). If your code has a reference or
2026-
pointer to the top-level `ZoneManager` interface, then it will be far easier to
2027-
create a `TimeZone` using `createForZoneId()`. You do pay a penalty in
2028-
efficiency because `createForZoneId()` must scan the database, where as
2029-
`createForZoneInfo()` does not perform a search since it has direct access to
2026+
(`basic::Info::ZoneInfo` and `extended::Info::ZoneInfo`). If your code has a
2027+
reference or pointer to the top-level `ZoneManager` interface, then it will be
2028+
far easier to create a `TimeZone` using `createForZoneId()`. You do pay a
2029+
penalty in efficiency because `createForZoneId()` must scan the database, where
2030+
as `createForZoneInfo()` does not perform a search since it has direct access to
20302031
the `ZoneInfo` data structure.
20312032

20322033
<a name="CreateForZoneIndex"></a>
@@ -2399,9 +2400,9 @@ defined in the `zoneinfo/ZoneInfoXxx.h` header files:
23992400
In v2.3, three versions of these ZoneInfo records were created, to support the 3
24002401
different zonedb types:
24012402

2402-
* `ace_time::basic::ZoneXxx` - used with `BasicZoneProcessor`
2403-
* `ace_time::extended::ZoneXxx` - used with `ExtendedZoneProcessor`
2404-
* `ace_time::complete::ZoneXxx` - used with `CompleteZoneProcessor`
2403+
* `ace_time::basic::Info::ZoneXxx` - used with `BasicZoneProcessor`
2404+
* `ace_time::extended::Info::ZoneXxx` - used with `ExtendedZoneProcessor`
2405+
* `ace_time::complete::Info::ZoneXxx` - used with `CompleteZoneProcessor`
24052406

24062407
Information stored in `PROGMEM` must be retrieved using special functions (e.g.
24072408
`pgm_read_byte()`, `pgm_read_word()`, etc). A thin layer of indirection is
@@ -2419,9 +2420,9 @@ abstraction layer is provided by `zoneinfo/Brokers.h`:
24192420
There are 3 sets of these broker classes, duplicated into 2 different C++
24202421
namespaces:
24212422

2422-
* `ace_time::basic::ZoneXxxBroker`
2423-
* `ace_time::extended::ZoneXxxBroker`
2424-
* `ace_time::complete::ZoneXxxBroker`
2423+
* `ace_time::basic::Info::ZoneXxxBroker`
2424+
* `ace_time::extended::Info::ZoneXxxBroker`
2425+
* `ace_time::complete::Info::ZoneXxxBroker`
24252426

24262427
The separate namespaces allows compile-time verification that the correct
24272428
`zonedb*` database is used with the correct `BasicZoneProcessor`,
@@ -2439,9 +2440,9 @@ general consumption:
24392440

24402441
These 3 are meant for unit tests:
24412442

2442-
* `zonedbtesting` for `BasicZoneProcessor`
2443-
* `zonedbxtesting` for `ExtendedZoneProcessor`
2444-
* `zonedbctesting` for `CompleteZoneProcessor`
2443+
* `testingzonedb` for `BasicZoneProcessor`
2444+
* `testingzonedbx` for `ExtendedZoneProcessor`
2445+
* `testingzonedbc` for `CompleteZoneProcessor`
24452446

24462447
<a name="BasicZonedb"></a>
24472448
#### Basic zonedb
@@ -2570,8 +2571,8 @@ was intended to be used by the client application:
25702571
using namespace ace_time;
25712572

25722573
void printStartAndUntilYears() {
2573-
ace_time::extended::ZoneInfoBroker info(&zonedbx::kZoneAmerica_Los_Angeles);
2574-
extended::ZoneContextBroker context = info.zoneContext();
2574+
ace_time::extended::Info::ZoneInfoBroker info(&zonedbx::kZoneAmerica_Los_Angeles);
2575+
extended::Info::ZoneContextBroker context = info.zoneContext();
25752576

25762577
Serial.print("startYear: ");
25772578
Serial.print(context.startYear()); // e.g. 2000
@@ -2596,12 +2597,12 @@ timezone were filtered out of the zone database.
25962597
<a name="ExternalZone"></a>
25972598
#### External Zone Classes
25982599

2599-
The `basic::ZoneInfo`, `extended::ZoneInfo`, and `complete::ZoneInfo` objects
2600-
are meant to be used as *opaque* pointers and simply passed into the `TimeZone`
2601-
class (which in turn, passes the pointer into the corresponding `ZoneProcessor`
2602-
objects.) The internal formats of the `ZoneInfo` structures may change without
2603-
warning, and users of this library should not access its internal data members
2604-
directly.
2600+
The `basic::Info::ZoneInfo`, `extended::Info::ZoneInfo`, and
2601+
`complete::Info::ZoneInfo` objects are meant to be used as *opaque* pointers and
2602+
simply passed into the `TimeZone` class (which in turn, passes the pointer into
2603+
the corresponding `ZoneProcessor` objects.) The internal formats of the
2604+
`ZoneInfo` structures may change without warning, and users of this library
2605+
should not access its internal data members directly.
26052606

26062607
Instead, client applications should use the `BasicZone`, `ExtendedZone`, and
26072608
`CompleteZone` classes which aims to provide stable external access to some of
@@ -2612,7 +2613,7 @@ namespace ace_time {
26122613

26132614
class BasicZone {
26142615
public:
2615-
BasicZone(const basic::ZoneInfo* zoneInfo);
2616+
BasicZone(const basic::Info::ZoneInfo* zoneInfo);
26162617

26172618
bool isNull() const;
26182619
uint32_t zoneId() const;
@@ -2625,7 +2626,7 @@ class BasicZone {
26252626

26262627
class ExtendedZone {
26272628
public:
2628-
ExtendedZone(const extended::ZoneInfo* zoneInfo);
2629+
ExtendedZone(const extended::Info::ZoneInfo* zoneInfo);
26292630

26302631
bool isNull() const;
26312632
uint32_t zoneId() const;
@@ -2675,7 +2676,7 @@ These objects are meant to be used transiently, created on the stack then thrown
26752676
away. For example:
26762677
26772678
```C++
2678-
const extended::ZoneInfo* zoneInfo = ...;
2679+
const extended::Info::ZoneInfo* zoneInfo = ...;
26792680
ExtendedZone(zoneInfo).printNameTo(Serial);
26802681
Serial.println();
26812682
```
@@ -2694,7 +2695,7 @@ zone name into the memory buffer, then extract the string from the buffer:
26942695
using ace_common::PrintStr;
26952696
...
26962697

2697-
const extended::ZoneInfo* zoneInfo = ...;
2698+
const extended::Info::ZoneInfo* zoneInfo = ...;
26982699
PrintStr<32> printStr; // buffer of 32 bytes on the stack
26992700
ExtendedZone(zoneInfo).printNameTo(printStr);
27002701

@@ -2770,15 +2771,15 @@ zones from the `zonedbx::` data set:
27702771
#include <AceTime.h>
27712772
using namespace ace_time;
27722773
...
2773-
static const extended::ZoneInfo* const kCustomRegistry[] ACE_TIME_PROGMEM = {
2774+
static const extended::Info::ZoneInfo* const kCustomRegistry[] ACE_TIME_PROGMEM = {
27742775
&zonedbx::kZoneAmerica_Los_Angeles,
27752776
&zonedbx::kZoneAmerica_Denver,
27762777
&zonedbx::kZoneAmerica_Chicago,
27772778
&zonedbx::kZoneAmerica_New_York,
27782779
};
27792780

27802781
static const uint16_t kCustomRegistrySize =
2781-
sizeof(kCustomRegistry) / sizeof(extended::ZoneInfo*);
2782+
sizeof(kCustomRegistry) / sizeof(extended::Info::ZoneInfo*);
27822783

27832784
static const uint16_t CACHE_SIZE = 2;
27842785
static ExtendedZoneProcessorCache<CACHE_SIZE> zoneProcessorCache;

0 commit comments

Comments
 (0)