You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Aug 3, 2026. It is now read-only.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,13 +7,14 @@ The format follows Keep a Changelog and the project adheres to Semantic Versioni
7
7
## [Unreleased]
8
8
### Added
9
9
-`ESPDateConfig::usePSRAMBuffers` to prefer PSRAM-backed allocation for ESPDate-owned text/state buffers (timezone, NTP server, scoped TZ restore state) through `ESPBufferManager`, with automatic fallback to normal heap.
10
+
- Multi-server NTP config support in `ESPDateConfig` via `ntpServer` (primary), `ntpServer2` (secondary), and `ntpServer3` (tertiary), with empty values ignored and compacted before calling `configTzTime`.
10
11
-`isDstActive` helper to detect whether daylight saving time is in effect using a provided POSIX TZ string, the stored TZ config, or the current system TZ.
11
12
- Moon phase calculation helpers returning phase angle and illumination for any `DateTime` (or `now()`).
12
13
- Local time helpers: `nowLocal()` plus `toLocal(DateTime[, tz])` expose broken-out local components and UTC offset for debugging sunrise/sunset and DST handling.
13
14
- Documented the recommended UTC storage + local UI workflow (convert user-picked local times back to UTC with `fromLocal`/`parseDateTimeLocal`).
14
15
-`setNtpSyncCallback(...)` so applications can optionally react when SNTP reports a successful sync.
15
16
-`setNtpSyncCallback(const NtpSyncCallable&)` overload so member methods can be registered via `std::bind`.
16
-
-`syncNTP()` to immediately trigger a new SNTP sync using the configured NTP server.
17
+
-`syncNTP()` to immediately trigger a new SNTP sync using the configured NTP server list.
17
18
-`ntpSyncIntervalMs` config field plus `setNtpSyncIntervalMs(...)` runtime setter to override SNTP sync interval when runtime support is available.
18
19
- Internal last-sync tracking plus `hasLastNtpSync()` / `lastNtpSync()` getters.
19
20
- String formatting helpers for `DateTime`/`LocalDateTime` with buffer-based APIs plus `std::string` convenience wrappers (`nowUtcString`, `nowLocalString`, etc.).
@@ -23,7 +24,7 @@ The format follows Keep a Changelog and the project adheres to Semantic Versioni
23
24
24
25
### Changed
25
26
- Replaced the `ESPDateConfig` constructor with an explicit `init(const ESPDateConfig&)` so configuration happens after the Arduino runtime is alive, avoiding early SNTP watchdog resets on some boards.
26
-
-`ESPDateConfig` now accepts an `ntpServer`; when provided alongside `timeZone`, `init` calls `configTzTime` to set the TZ and bootstrap SNTP automatically.
27
+
-`ESPDateConfig` now accepts up to three NTP servers; when at least one is provided alongside `timeZone`, `init` calls `configTzTime` to set the TZ and bootstrap SNTP automatically.
27
28
28
29
### Fixed
29
30
- Restored builds by adding the missing internal `utils.h` helpers referenced by the sun/scheduler code paths.
Copy file name to clipboardExpand all lines: README.md
+15-6Lines changed: 15 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ ESPDate is a tiny C++17 helper for ESP32 projects that makes working with dates
19
19
-**Sunrise / sunset**: compute daily sun times from lat/lon using numeric offsets or POSIX TZ strings (auto-DST aware).
20
20
-**DST detection**: `isDstActive` reports whether daylight saving time applies using the stored TZ, an explicit POSIX TZ string, or the current system TZ.
21
21
-**Moon phase**: `moonPhase` returns the current lunar phase angle and illumination fraction for any moment.
22
-
-**Optional NTP bootstrap**: call `init` with `ESPDateConfig` containing both `timeZone` and `ntpServer` to set TZ and start SNTP after Arduino/WiFi is ready.
22
+
-**Optional NTP bootstrap**: call `init` with `ESPDateConfig` containing `timeZone` and at least one NTP server (`ntpServer`, optional `ntpServer2`/`ntpServer3`) to set TZ and start SNTP after Arduino/WiFi is ready.
23
23
-**NTP sync callback + manual re-sync**: register `setNtpSyncCallback(...)` with a function, lambda, or `std::bind`, call `syncNTP()` anytime to trigger an immediate refresh, and optionally override SNTP interval via `ntpSyncIntervalMs` / `setNtpSyncIntervalMs(...)`.
24
24
-**Optional PSRAM-backed config/state buffers**: `ESPDateConfig::usePSRAMBuffers` routes ESPDate-owned text state (timezone/NTP/scoped TZ restore buffers) through `ESPBufferManager` with automatic fallback.
25
25
-**Explicit lifecycle cleanup**: `deinit()` unregisters ESPDate-owned SNTP callback hooks, clears runtime config buffers, and is safe to call repeatedly; the destructor calls it automatically.
@@ -31,8 +31,8 @@ ESPDate is a tiny C++17 helper for ESP32 projects that makes working with dates
31
31
-**Class-based API**: everything hangs off a single `ESPDate` instance; no global namespace clutter.
32
32
-**Lightweight & portable**: C++17, header-first public API; relies only on standard C time functions and the system clock (`time()`).
33
33
34
-
ESPDate does not configure SNTP by default. Call `init` with a POSIX TZ string plus an `ntpServer`to have ESPDate call `configTzTime` for you—do this after the Arduino runtime and WiFi are up to avoid early watchdog resets. Otherwise you remain in control of time-zone setup and system clock sync.
35
-
`syncNTP()` returns `true` only when an NTP server is configured and the runtime supports `configTzTime`.
34
+
ESPDate does not configure SNTP by default. Call `init` with a POSIX TZ string plus at least one NTP server (`ntpServer`, optional `ntpServer2`/`ntpServer3`) to have ESPDate call `configTzTime` for you. Do this after the Arduino runtime and WiFi are up to avoid early watchdog resets. Otherwise you remain in control of time-zone setup and system clock sync.
35
+
`syncNTP()` returns `true` only when one or more NTP servers are configured and the runtime supports `configTzTime`.
36
36
SNTP exposes a system-level sync hook, so the last `setNtpSyncCallback(...)` registration is the active callback.
37
37
For the same reason, `lastNtpSync()` is tracked on the currently active `ESPDate` instance.
38
38
Example member-method binding style:
@@ -63,9 +63,12 @@ void setup() {
63
63
64
64
// Configure TZ + NTP after WiFi is connected if you want ESPDate to call configTzTime
- ESPDate configures SNTP only when you call `init` with both `timeZone` and `ntpServer`in `ESPDateConfig` (it calls `configTzTime`). Call it after WiFi is up, or ensure the device clock is set before calling `now()`. Sunrise/sunset use either the stored TZ string (if provided) or the current process TZ—make sure it matches the coordinates you pass.
484
+
- ESPDate configures SNTP only when you call `init` with `timeZone` and at least one configured NTP server (`ntpServer`, `ntpServer2`, or `ntpServer3`) in `ESPDateConfig` (it calls `configTzTime`). Empty server strings are ignored and compacted. Call it after WiFi is up, or ensure the device clock is set before calling `now()`. Sunrise/sunset use either the stored TZ string (if provided) or the current process TZ; make sure it matches the coordinates you pass.
476
485
- All arithmetic and comparisons are UTC-first. Local helpers rely on the current process TZ (`setenv("TZ", ...)`, `tzset()`); make sure that matches your deployment.
477
486
- Month/year arithmetic clamps to the last valid day of the target month (e.g., Jan 31 + 1 month → Feb 28/29; Feb 29 - 1 year → Feb 28).
478
487
-`differenceInDays` is purely `seconds / 86400` truncated toward zero, not a calendar-boundary delta.
0 commit comments