fix+perf: corrections de revue (currentEcheance, dayOfYear, SWR, last-good, doc apikey)
- vigilance: currentEcheance basée sur productDatetime (jour calme renvoyait J1 à tort)
- normales: dayOfYear extrait en Europe/Paris pour 'now' (UTC mélangeait les jours après minuit)
- meteofrance-auth + CLAUDE.md: header `apikey:` documenté correctement (pas Authorization Bearer)
- cache: SWR — envelope {v, fu}, hard TTL = ttl*6, refresh background avec lock anti-stampede
- vigilance: snapshot last-good (TTL 30j) écrit à chaque fetch, fallback final si MF+ODS KO
- vigilance: nettoyage variable url morte dans fetchOpendatasoft
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e72f25b33d
commit
290f9be7b9
5 changed files with 201 additions and 45 deletions
|
|
@ -27,12 +27,19 @@ export interface DailyNormale {
|
|||
}
|
||||
|
||||
// Day-of-year en convention "leap calendar" (1..366), aligné sur le calendrier bissextile.
|
||||
// Les années non-bissextiles : on bascule simplement le 1er mars au doy 60 si pas 29 fév.
|
||||
// Mais pour matcher l'indexation du JSON (1..366), on utilise une convention stable.
|
||||
// Extraction Y/M/D en Europe/Paris pour rester cohérent avec :
|
||||
// - les pages SSR qui formatent en Europe/Paris (todayLabel, productDate),
|
||||
// - les obs climato YYYY-MM-DD (parsées en UTC midnight, donc Paris == J ou J-1
|
||||
// selon offset DST, mais ça représente toujours la "journée Paris" du jour
|
||||
// suivant — assez proche pour le lookup normale).
|
||||
// - `new Date()` (now) : en UTC, getUTC* renvoie hier entre 00h et 01h/02h Paris.
|
||||
// Toujours utiliser le jour Paris-local.
|
||||
export function dayOfYear(date: Date): number {
|
||||
const y = date.getUTCFullYear();
|
||||
const m = date.getUTCMonth() + 1;
|
||||
const d = date.getUTCDate();
|
||||
// sv-SE → format "YYYY-MM-DD"
|
||||
const iso = date.toLocaleDateString('sv-SE', { timeZone: 'Europe/Paris' });
|
||||
const y = parseInt(iso.slice(0, 4), 10);
|
||||
const m = parseInt(iso.slice(5, 7), 10);
|
||||
const d = parseInt(iso.slice(8, 10), 10);
|
||||
const cumulNonLeap = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||
const cumulLeap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
|
||||
const isLeap = (y % 4 === 0 && y % 100 !== 0) || (y % 400 === 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue