Bibliothèque PlatformIO/Arduino permettant de déterminer le fuseau horaire (IANA timezone ID) à partir de coordonnées GPS (latitude/longitude en degrés), avec gestion de l'heure d'été/d'hiver (DST).
- Lecture du fichier binaire
timezone21.binoutimezone16.bin(format ZoneDetect) depuis une carte SD (ou tout autreStreamseekable) - Retourne le timezone ID IANA (ex.
"Europe/Paris") - Calcul de l'offset UTC courant incluant le DST via un fichier
dst_rules.bingénéré par un script Python - Compatible Arduino et ESP32
- Faible empreinte mémoire : zéro allocation dynamique dans le chemin critique
| Fichier | Source |
|---|---|
timezone21.bin ou timezone16.bin |
Répertoire database/out/ du dépôt BertoldVdb/ZoneDetect (utiliser out/, pas out_v1/) |
dst_rules.bin |
Généré par tools/generate_dst_bin.py |
Important : utilisez uniquement les fichiers du répertoire
out/(version 0). Le répertoireout_v1/contient des fichiers compressés (version 1) qui ne sont pas pris en charge.
#include <SD.h>
#include "ZoneDetect.h"
#include "DST.h"
ZoneDetect zd;
DST dst;
void setup() {
SD.begin();
// Les fichiers et readers doivent survivre à setup() → déclarés static
static File tzFile = SD.open("/timezone21.bin");
static ZDFileReader<File> tzReader(tzFile);
zd.begin(&tzReader);
static File dstFile = SD.open("/dst_rules.bin");
static ZDFileReader<File> dstReader(dstFile);
dst.begin(&dstReader);
}
void loop() {
char tzId[48];
zd.getTimezoneId(48.8584f, 2.2945f, tzId, sizeof(tzId));
// tzId == "Europe/Paris"
uint32_t utcNow = 1711846800UL; // 2024-03-31 01:00:00 UTC
int32_t offsetSec = 0;
if (dst.getUtcOffset(tzId, utcNow, offsetSec)) {
// offsetSec = +7200 (CEST = UTC+2)
} else {
// tzId not found in dst_rules.bin
}
uint32_t localUnix = dst.toLocalTime(tzId, utcNow); // 0 = error
// Compatible with RTClib:
// DateTime localDt(localUnix);
}Important : les objets
FileetZDFileReaderdoivent rester en vie aussi longtemps queZoneDetectetDSTsont utilisés. Déclarez-lesstaticdanssetup()ou comme variables globales — jamais en variables locales non-statiques, sinon le pointeur interne devient invalide et provoque un crash (InstrFetchProhibited).
bool begin(ZDReader *reader);
int lookup(float lat, float lon, ZDMatch *out, uint8_t maxResults = 1);
bool getTimezoneId(float lat, float lon, char *tzId, size_t bufLen);ZDMatch contient :
tzId[48]– identifiant IANA (ex."America/New_York")countryA2[3]– code pays ISO-3166 (ex."US")
bool begin(ZDReader *reader);
bool getPosixTz(const char *tzId, char *posixTz, size_t bufLen);
// Offset UTC en secondes. Renvoie false si tzId absent de dst_rules.bin.
// Plage : -43 200 (UTC-12) … +50 400 (UTC+14) → int32_t requis (> int16_t max).
bool getUtcOffset(const char *tzId, uint32_t utcUnix, int32_t &offsetSec);
// Temps local Unix (= utcUnix + offset). Renvoie 0 en cas d'erreur.
// Directement compatible RTClib : DateTime dt(dst.toLocalTime(tzId, utcUnix));
uint32_t toLocalTime(const char *tzId, uint32_t utcUnix);
// Utilisation sans fichier (chaîne POSIX TZ connue à l'avance)
static int32_t parsePosixTz(const char *posixTz, uint32_t utcUnix);Abstraction seekable. Wrapper générique pour tout objet SD-like :
ZDFileReader<File> reader(sdFile); // File = SD.h File, SPIFFS File, etc.Pour un source personnalisé, implémentez ZDReader :
class MonReader : public ZDReader {
bool seek(uint32_t pos) override { ... }
uint32_t position() override { ... }
size_t readBytes(uint8_t *buf, size_t len) override { ... }
uint32_t fileSize() override { ... }
};pip install pytz
cd tools
python3 generate_dst_bin.py -o dst_rules.bin
# Toutes les timezones (~600 entrées, ~40 Ko)
# Ou seulement les zones souhaitées :
python3 generate_dst_bin.py -z Europe/Paris America/New_York Pacific/Auckland -o dst_rules.bin4 octets "DSTR" (magic)
2 octets uint16 LE nombre d'entrées N
par entrée :
uint8 longueur du tzId
bytes tzId (sans null)
uint8 longueur de la chaîne POSIX TZ
bytes chaîne POSIX TZ (sans null)
timezone21.bin: précision ~100 m (recommandé)timezone16.bin: précision ~3 km (fichier plus petit, adapté aux microcontrôleurs avec moins de mémoire Flash/SD)
Aucune dépendance externe. Nécessite uniquement la bibliothèque SD (incluse dans l'IDE Arduino / PlatformIO) pour la lecture de fichiers.
MIT