diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 87b918a4e..71aa36964 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -2221,6 +2221,7 @@ accessible name remains "Don't show this again". Control behavior is unchanged. ## FIRMS source status The FIRMS CSV parser rejects impossible acquisition calendar dates before the proxy filters records to the trailing 24 hours, while retaining valid UTC acquisition times. +FIRMS ages round to whole hours before choosing a unit, so a 47.6-hour age reads "2d", not "48h". The `get_active_fires` tool reports acquisition times as UTC ISO timestamps, including zero-padded hours and minutes; missing or invalid dates and times remain `null`, including impossible calendar dates from a custom source. diff --git a/src/layers/firms/model.js b/src/layers/firms/model.js index 9e3cf7f95..7dcf255c8 100644 --- a/src/layers/firms/model.js +++ b/src/layers/firms/model.js @@ -526,7 +526,8 @@ export function createModel({ if (!Number.isFinite(deltaMs) || deltaMs < 0) return ''; const hours = deltaMs / 3600000; if (hours < 1) return '<1h'; - if (hours < 48) return `${Math.round(hours)}h`; + const wholeHours = Math.round(hours); + if (wholeHours < 48) return `${wholeHours}h`; return `${Math.round(hours / 24)}d`; } @@ -561,8 +562,9 @@ export function createModel({ if (!Number.isFinite(deltaMs) || deltaMs < 0) return ''; const hours = deltaMs / 3600000; if (hours < 1) return t('<1h', { context: 'age' }); - if (hours < 48) - return t('{count}h', { context: 'age', count: Math.round(hours) }); + const wholeHours = Math.round(hours); + if (wholeHours < 48) + return t('{count}h', { context: 'age', count: wholeHours }); return t('{count}d', { context: 'age', count: Math.round(hours / 24) }); } diff --git a/src/layers/firms/model.test.mjs b/src/layers/firms/model.test.mjs new file mode 100644 index 000000000..7ff12cf3f --- /dev/null +++ b/src/layers/firms/model.test.mjs @@ -0,0 +1,24 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { getLocale, setLocale } from '../../i18n/index.js'; +import { createModel } from './model.js'; + +const HOUR_MS = 3600000; + +test('a fire age that rounds to 48 hours reads in days, as 48 hours does', () => { + const previousLocale = getLocale(); + const { formatAge, formatAgeLabel } = createModel({ + services: { anchors: {} }, + }); + try { + setLocale('en'); + assert.equal(formatAge(47.4 * HOUR_MS), '47h'); + assert.equal(formatAge(47.6 * HOUR_MS), '2d'); + assert.equal(formatAge(48 * HOUR_MS), '2d'); + assert.equal(formatAgeLabel(47.4 * HOUR_MS), '47h'); + assert.equal(formatAgeLabel(47.6 * HOUR_MS), formatAgeLabel(48 * HOUR_MS)); + assert.equal(formatAgeLabel(48 * HOUR_MS), '2d'); + } finally { + setLocale(previousLocale); + } +});