Skip to content

Commit 1f00841

Browse files
authored
Merge pull request #20 from bxparks/develop
0.8.1 - update SystemClockCoroutine for compatibility with AceRoutine v0.3
2 parents 5f6d640 + f778ba8 commit 1f00841

File tree

14 files changed

+101
-100
lines changed

14 files changed

+101
-100
lines changed

CHANGELOG.md

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

33
* Unreleased
4+
* 0.8.1
5+
* Update `SystemClockCoroutine` to be compatible with
6+
`COROUTINE_DELAY_SECONDS()` API changed in AceRoutine v0.3.
7+
* Fix typos and grammar errors in `USER_GUIDE.md` and `README.md`.
8+
* Remove `YearMonth` abstraction in `BasicZoneProcessor`, saving 12 bytes
9+
of flash in WorldClock.
410
* 0.8
511
* Handle `Fri<=1` correctly in various python scripts. (#17)
612
* Improve resolution of zonedb files and ZoneProcessor classes. (#18)

README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,21 +73,22 @@ C++ namespaces:
7373
The "date and time" classes provide an abstraction layer to make it easier
7474
to use and manipulate date and time fields. For example, each of the
7575
`LocalDateTime`, `OffsetDateTime` and `ZonedDateTime` classes provide the
76-
`toEpochSeconds()` which returns the number of seconds from a epoch date, the
77-
`forEpochSeconds()` which constructs the date and time fields from the epoch
78-
seconds, the `forComponents()` method which constructs the object from the
79-
individual (year, month, day, hour, minute, second) components, and the
76+
`toEpochSeconds()` method which returns the number of seconds from an epoch
77+
date, the `forEpochSeconds()` method which constructs the date and time fields
78+
from the epoch seconds, the `forComponents()` method which constructs the object
79+
from the individual (year, month, day, hour, minute, second) components, and the
8080
`dayOfWeek()` method which returns the day of the week of the given date.
8181

8282
The Epoch in AceTime is defined to be 2000-01-01T00:00:00Z, in contrast to the
8383
Epoch in Unix which is 1970-01-01T00:00:00Z. Internally, the current time is
8484
represented as "seconds from Epoch" stored as a 32-bit signed integer
85-
(`acetime_t` aliased to `int32_t`). The smallest 32-bit signed
86-
integer (`-2^31`) is used to indicate an internal Error condition, so the
87-
range of valid `acetime_t` value is `-2^31+1` to `2^31-1`.
88-
Therefore, the range of dates that the `acetime_t` type can handle is
89-
1931-12-13T20:45:53Z to 2068-01-19T03:14:07Z (inclusive). (In contrast, the
90-
32-bit Unix `time_t` range is 1901-12-13T20:45:52Z to 2038-01-19T03:14:07Z).
85+
(`acetime_t` aliased to `int32_t`). The smallest 32-bit signed integer (`-2^31`)
86+
is used to indicate an internal Error condition, so the range of valid
87+
`acetime_t` value is `-2^31+1` to `2^31-1`. Therefore, the range of dates that
88+
the `acetime_t` type can handle is 1931-12-13T20:45:53Z to 2068-01-19T03:14:07Z
89+
(inclusive). (In contrast, the 32-bit Unix `time_t` range is
90+
1901-12-13T20:45:52Z to 2038-01-19T03:14:07Z which is the cause of the [Year
91+
2038 Problem](https://en.wikipedia.org/wiki/Year_2038_problem)).
9192

9293
The various date classes (`LocalDate`, `LocalDateTime`, `OffsetDateTime`,
9394
`ZonedDateTime`) store the year component internally as a signed 8-bit integer
@@ -208,7 +209,7 @@ Conversion from an epochSeconds to date-time components including timezone
208209
* 2.8 microseconds on an ESP32,
209210
* 6 microseconds on a Teensy 3.2.
210211

211-
**Version**: 0.8 (2019-08-19, TZ DB version 2019b, beta)
212+
**Version**: 0.8.1 (2019-08-26, TZ DB version 2019b, beta)
212213

213214
**Status**: Supports 1-minute resolution for all Extended TimeZones, and
214215
validated against Hinnant date library from 1975 until 2050. I think this will

USER_GUIDE.md

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
See the [README.md](README.md) for introductory background.
44

5-
Version: 0.8 (2019-08-19, TZ DB version 2019b, beta)
5+
Version: 0.8.1 (2019-08-26, TZ DB version 2019b, beta)
66

77
## Installation
88

@@ -152,7 +152,7 @@ application, and it will instantly use the new transition rules, without the
152152
developer needing to create a new POSIX string. To address the memory constraint
153153
problem, the AceTime library is designed to load only of the smallest subset of
154154
the TZ Database that is required to support the selected timezones (1 to 3 have
155-
fully been tested). Dynamic lookup of the time zone is possible using the
155+
been extensively tested). Dynamic lookup of the time zone is possible using the
156156
`ZoneManager`, and the app develop can customize it with the list of zones that
157157
are compiled into the app. On microcontrollers with more than about 32kB of
158158
flash memory (e.g. ESP8266, ESP32, Teensy 3.2) and depending on the size of the
@@ -638,7 +638,7 @@ observing Daylight Saving Time (DST).
638638

639639
An `OffsetDateTime` is an object that can represent a `LocalDateTime` which is
640640
offset from the UTC time zone by a fixed amount. Internally the `OffsetDateTime`
641-
is a aggregation of `LocalDateTime` and `TimeOffset`. Use this class for
641+
is an aggregation of `LocalDateTime` and `TimeOffset`. Use this class for
642642
creating and writing timestamps for events which are destined for logging for
643643
example. This class does not know about Daylight Saving Time transitions.
644644

@@ -743,9 +743,9 @@ be encoded with (relatively) simple rules from the TZ Database
743743
* `TimeZone::kTypeExtended`: utilizes a `ExtendedZoneProcessor` which can
744744
handle all zones in the TZ Database
745745
* `TimeZone::kTypeBasicManaged`: same as `kTypeBasic` but the
746-
`BasicZoneProcessor` is managed by the `ZoneManager
746+
`BasicZoneProcessor` is managed by the `ZoneManager`
747747
* `TimeZone::kTypeExtendedManaged`: same as `kTypeExtended` but the
748-
`ExtendedZoneProcessor` is managed by the `ZoneManager
748+
`ExtendedZoneProcessor` is managed by the `ZoneManager`
749749

750750
The class hierarchy of `TimeZone` is shown below, where the arrow means
751751
"is-subclass-of" and the diamond-line means "is-aggregation-of". This is an
@@ -760,8 +760,8 @@ hold a reference to:
760760
`kTypeExtendedManaged`).
761761

762762
```
763-
.------------------------------.
764-
<>' 0..1 \ 0..1
763+
.-------------------------------.
764+
<> 0..1 \ 0..1
765765
TimeZone <>-------- ZoneProcessor ------- ZoneProcessorCache
766766
^ ^
767767
| |
@@ -910,7 +910,7 @@ void someFunction() {
910910

911911
The zoneinfo files were generated by a script using the TZ Database. This header
912912
file is already included in `<AceTime.h>` so you don't have to explicitly
913-
include it. As of version 2019a of the database, it contains 270 Zone and 182
913+
include it. As of version 2019b of the database, it contains 270 Zone and 182
914914
Link entries and whose time change rules are simple enough to be supported by
915915
`BasicZoneProcessor`. The bottom of the `zone_infos.h` header file lists 117
916916
zones whose zone rules are too complicated for `BasicZoneProcessor`.
@@ -987,7 +987,7 @@ namespace. Although the data structures in the 2 namespaces are identical
987987
currently (v0.8) but the *values* inside the data structure fields are not
988988
the same, and they are interpreted differently.)
989989

990-
As of version 2019a of TZ Database, *all* 387 Zone and 205 Link entries from the
990+
As of version 2019b of TZ Database, *all* 387 Zone and 205 Link entries from the
991991
following TZ files are supported: `africa`, `antarctica`, `asia`, `australasia`,
992992
`backward`, `etcetera`, `europe`, `northamerica`, `southamerica`. There are 3
993993
files which are not processed (`backzone`, `systemv`, `factory`) because they
@@ -1465,18 +1465,19 @@ is a `BasicZoneManager` with only 4 zones from the `zonedb::` data set:
14651465
#include <AceTime.h>
14661466
using namespace ace_time;
14671467
...
1468-
static const basic::ZoneInfo* const kBasicZoneRegistry[] ACE_TIME_PROGMEM = {
1468+
static const basic::ZoneInfo* const kZoneRegistry[] ACE_TIME_PROGMEM = {
14691469
&zonedb::kZoneAmerica_Los_Angeles,
14701470
&zonedb::kZoneAmerica_Denver,
14711471
&zonedb::kZoneAmerica_Chicago,
14721472
&zonedb::kZoneAmerica_New_York,
14731473
};
14741474

14751475
static const uint16_t kZoneRegistrySize =
1476-
sizeof(Controller::kZoneRegistry) / sizeof(basic::ZoneInfo*);
1476+
sizeof(kZoneRegistry) / sizeof(basic::ZoneInfo*);
14771477

1478-
static const uint16_t NUM_ZONES = 2;
1479-
static BasicZoneManager<NUM_ZONES> zoneManager(kZoneRegistrySize, kZoneRegistry);
1478+
static const uint16_t CACHE_SIZE = 2;
1479+
static BasicZoneManager<CACHE_SIZE> zoneManager(
1480+
kZoneRegistrySize, kZoneRegistry);
14801481
```
14811482
14821483
Here is the equivalent `ExtendedZoneManager` with 4 zones from the `zonedbx::`
@@ -1494,10 +1495,11 @@ static const extended::ZoneInfo* const kZoneRegistry[] ACE_TIME_PROGMEM = {
14941495
};
14951496
14961497
static const uint16_t kZoneRegistrySize =
1497-
sizeof(Controller::kZoneRegistry) / sizeof(extended::ZoneInfo*);
1498+
sizeof(kZoneRegistry) / sizeof(extended::ZoneInfo*);
14981499
1499-
static const uint16_t NUM_ZONES = 2;
1500-
static ExtendedZoneManager<NUM_ZONES> zoneManager(kZoneRegistrySize, kZoneRegistry);
1500+
static const uint16_t CACHE_SIZE = 2;
1501+
static ExtendedZoneManager<CACHE_SIZE> zoneManager(
1502+
kZoneRegistrySize, kZoneRegistry);
15011503
```
15021504

15031505
The `ACE_TIME_PROGMEM` macro is defined in
@@ -1510,7 +1512,7 @@ according to this macro.
15101512
See [CommandLineClock](examples/CommandLineClock/) for an example of how these
15111513
custom registries can be created and used.
15121514

1513-
#### createForZoneName
1515+
#### createForZoneName()
15141516

15151517
The `ZoneManager` allows creation of a `TimeZone` using the fully qualified
15161518
zone name:
@@ -1539,7 +1541,7 @@ I think the only time the `createForZoneName()` might be useful is if
15391541
the user was allowed to type in the zone name, and you wanted to create a
15401542
`TimeZone` from the string typed in by the user.
15411543

1542-
#### createForZoneId
1544+
#### createForZoneId()
15431545

15441546
Each zone in the `zonedb::` and `zonedbx::` database is given a unique
15451547
and stable zoneId. This can be retrieved from the `TimeZone` object using:
@@ -1600,21 +1602,21 @@ check for this, and substitute a reasonable default TimeZone when this happens.
16001602
This situation is not unique to the zoneId. The same problem would occur if the
16011603
fully qualified zone name was used.
16021604

1603-
#### createForZoneIndex
1605+
#### createForZoneIndex()
16041606

16051607
The `ZoneManager::createForZoneIndex()` creates a `TimeZone` from its integer
16061608
index into the Zone registry, from 0 to `registrySize - 1`. This is useful when
16071609
you want to show the user with a menu of zones from the `ZoneManager` and allow
16081610
the user to select one of the options.
16091611

1610-
The `ZoneManager::indexForZoneNmae()` and `ZoneManager::indexForZoneId()` are
1612+
The `ZoneManager::indexForZoneName()` and `ZoneManager::indexForZoneId()` are
16111613
two useful methods to convert an arbitrary time zone reference (either
16121614
by zoneName or zoneId) into an index into the registry.
16131615

16141616
### TZ Database Version
16151617

16161618
The IANA TZ Database is updated continually. As of this writing, the latest
1617-
stable version is 2019a. When a new version of the database is released, it is
1619+
stable version is 2019b. When a new version of the database is released, it is
16181620
relatively easy to regenerate the `zonedb/` and `zonedbx/` zoneinfo files.
16191621
However, it is likely that I would delay the release of a new version until the
16201622
corresponding `pytz` package is updated to the latest TZ database version, so
@@ -2420,8 +2422,8 @@ library for all timezones from 2000 to 2049 (inclusive):
24202422
* [BasicValidationUsingHinnantDateTest](tests/validation/BasicValidationUsingHinnantDateTest/)
24212423
* [ExtendedValidationUsingHinnantDateTest](tests/validation/ExtendedValidationUsingHinnantDateTest/)
24222424
2423-
I have validated the AceTime library against the following versions against
2424-
the Hinnant date library:
2425+
I have validated the AceTime library with the following TZ versions against
2426+
the Hinnant date library with the same TZ version:
24252427
24262428
* TZ Database: 2019a
24272429
* TZ Database: 2019b
@@ -2649,19 +2651,21 @@ some time to take a closer look in the future.
26492651
* This library does not support
26502652
[leap seconds](https://en.wikipedia.org/wiki/Leap_second) and will
26512653
probably never do so.
2652-
* The library does not implement TAI (International Atomic Time).
2654+
* The library does not implement
2655+
[TAI (International Atomic Time)](https://en.wikipedia.org/wiki/International_Atomic_Time).
26532656
* The `epochSeconds` is like `unixSeconds` in that it is unaware of
2654-
leap seconds. When a leap seconds occurs the `epochSeconds` is repeated
2655-
over 2 seconds, just like `unixSeconds`.
2657+
leap seconds. When a leap seconds occurs, the `epochSeconds` is held
2658+
constant over 2 seconds, just like `unixSeconds`.
26562659
* The `SystemClock` is unaware of leap seconds so it will continue
26572660
to increment `epochSeconds` through the leap second. In other words,
2658-
the SystemClock will be 1 second ahead of UTC.
2661+
the SystemClock will be 1 second ahead of UTC after the leap second
2662+
occurs.
26592663
* If the referenceClock is the `NtpClock`, that clock happens to
26602664
be leap second aware, and the `epochSeconds` will bounce back one
26612665
second upon the next synchronization, becoming synchronized to UTC.
26622666
* If the referenceClock is the `DS3231Clock`, that clock is *not*
26632667
leap second aware, so the `epochSeconds` will continue to be ahead of
2664-
UTC by one second.
2668+
UTC by one second even after synchronization.
26652669
* `acetime_t`
26662670
* AceTime uses an epoch of 2000-01-01T00:00:00Z.
26672671
The `acetime_t` type is a 32-bit signed integer whose smallest value
@@ -2821,7 +2825,7 @@ some time to take a closer look in the future.
28212825
* The SAMD21 microcontroller does *not* provide any EEPROM. Therefore,
28222826
this feature is disabled in the apps under `examples` (e.g.
28232827
`CommandLineClock`, `OledClock`, and `WorldClock`) which use this feature.
2824-
* The `MKR Zero` board generates *far* faster code (30%?) than the `SparkFun
2828+
* The `MKR Zero` board generates far faster code (30%?) than the `SparkFun
28252829
SAMD21 Mini Breakout` board. The `MKR Zero` could be using a different
28262830
(more recent?) version of the GCC tool chain. I have not investigated
28272831
this.

examples/OledClock/OledClock.ino

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ void setup() {
175175
#endif
176176

177177
#if ENABLE_SERIAL == 1
178-
SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux
179-
while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro
178+
SERIAL_PORT_MONITOR.begin(115200);
179+
while (!SERIAL_PORT_MONITOR); // Leonardo/Micro
180180
SERIAL_PORT_MONITOR.println(F("setup(): begin"));
181181
SERIAL_PORT_MONITOR.print(F("sizeof(ClockInfo): "));
182182
SERIAL_PORT_MONITOR.println(sizeof(ClockInfo));
@@ -204,7 +204,7 @@ void setup() {
204204
controller.setup();
205205
persistentStore.setup();
206206

207-
systemClock.setupCoroutine(F("systemClock"));
207+
systemClock.setupCoroutine(F("clock"));
208208
CoroutineScheduler::setup();
209209

210210
#if ENABLE_SERIAL == 1

examples/OledClock/Presenter.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ class Presenter {
111111
mOled.setFont(fixed_bold10x15);
112112
const ZonedDateTime& dateTime = mRenderingInfo.dateTime;
113113
if (dateTime.isError()) {
114-
mOled.println(F("9999-99-99"));
115-
mOled.println(F("99:99:99 "));
116-
mOled.println(F("Error "));
114+
mOled.println(F("<Error>"));
117115
return;
118116
}
119117

@@ -198,16 +196,12 @@ class Presenter {
198196
typeString = F("manual");
199197
break;
200198
case TimeZone::kTypeBasic:
199+
case TimeZone::kTypeBasicManaged:
201200
typeString = F("basic");
202201
break;
203202
case TimeZone::kTypeExtended:
204-
typeString = F("extd");
205-
break;
206-
case TimeZone::kTypeBasicManaged:
207-
typeString = F("bas-man");
208-
break;
209203
case TimeZone::kTypeExtendedManaged:
210-
typeString = F("extd-man");
204+
typeString = F("extd");
211205
break;
212206
default:
213207
typeString = F("unknown");
@@ -266,15 +260,12 @@ class Presenter {
266260
#if ENABLE_SERIAL == 1
267261
SERIAL_PORT_MONITOR.println(F("displayAbout()"));
268262
#endif
269-
mOled.setFont(SystemFont5x7);
270263

271264
// Use F() macros for these longer strings. Seems to save both
272265
// flash memory and RAM.
273-
mOled.print(F("OledClock: "));
274-
mOled.println(CLOCK_VERSION_STRING);
275266
mOled.print(F("TZ: "));
276267
mOled.println(zonedb::kTzDatabaseVersion);
277-
mOled.print(F("AceTime: "));
268+
mOled.print(F("AT: "));
278269
mOled.print(ACE_TIME_VERSION_STRING);
279270
}
280271

examples/OledClock/config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@
3939
#define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231
4040
#define OLED_REMAP false
4141
#elif defined(AUNITER_MICRO) || defined(AUNITER_MICRO_MINDER)
42+
// Pro Micro does not have enough Flash to use Basic TimeZone
43+
// (28884 bytes) so use Manual TimeZone (23984 bytes).
44+
#undef TIME_ZONE_TYPE
45+
#define TIME_ZONE_TYPE TIME_ZONE_TYPE_MANUAL
4246
#define MODE_BUTTON_PIN 8
4347
#define CHANGE_BUTTON_PIN 9
4448
#define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231

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=0.8
2+
version=0.8.1
33
author=Brian T. Park <[email protected]>
44
maintainer=Brian T. Park <[email protected]>
55
sentence=Date, time, clock, and TZ Database timezones for Arduino.

src/AceTime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
#include "ace_time/clock/SystemClockCoroutine.h"
5656

5757
// Version format: xxyyzz == "xx.yy.zz"
58-
#define ACE_TIME_VERSION 800
59-
#define ACE_TIME_VERSION_STRING "0.8"
58+
#define ACE_TIME_VERSION 801
59+
#define ACE_TIME_VERSION_STRING "0.8.1"
6060

6161
#endif

0 commit comments

Comments
 (0)