Formatting
These helpers turn stored values into text for screens, PDFs and tables. They are framework-free and are shared by the welldot.org editor and @welldot/pdf. Anything that needs translated words takes them as plain strings, so you keep your own message catalog.
Numbers
Floating-point arithmetic produces values like 39.99998784. formatNumber bounds the decimals so that noise never reaches the reader:
import { formatNumber } from '@welldot/utils';
formatNumber(39.99998784, { fractionDigits: 2, suffix: 'm' }); // '40.00 m'
formatNumber(1234.5, { locale: 'pt-BR', maximumFractionDigits: 1 }); // '1.234,5'
formatNumber(undefined); // '—'
Options: fractionDigits (fixed), minimumFractionDigits, maximumFractionDigits, suffix, locale (a BCP 47 tag, default en-US) and fallback (default —, shown for null, undefined and NaN). An absent value shows as a dash, never as 0, following the format's "absent means unknown" rule.
Dates
The format has two kinds of temporal values (datetime conventions): calendar dates (YYYY-MM-DD, for construction and permits) and instants (RFC 3339 with an offset, for everything measured). Handle them differently:
import {
formatCalendarDate,
formatDate,
fromCalendarDate,
toCalendarDate,
} from '@welldot/utils';
formatCalendarDate('2025-03-01'); // '01/03/2025', no time zone shift
formatCalendarDate('2025-03-01', 'yyyy-MM-dd'); // any date-fns pattern
formatDate(new Date('2025-03-01T10:00:00Z')); // 'dd/MM/yyyy HH:mm' in the runtime's time zone
toCalendarDate(new Date(2025, 2, 1)); // '2025-03-01', from a local Date, never through UTC
fromCalendarDate('2025-03-01'); // a local Date, or null when malformed
new Date('2025-03-01'): JavaScript reads it as UTC midnight, which is the previous day in the Americas. Use fromCalendarDate and formatCalendarDate.For the local date of an instant at the well site, use instantLocalDate(instant, timeZone) with the zone from getWellTimeZone(well) (Permits).
Coordinates
import { formatCoord, parseToDd } from '@welldot/utils';
formatCoord(-1.4558, 'DMS', true); // `1°27'20.88"S` (true = latitude)
formatCoord(-1.4558, 'DD', true); // '-1.455800'
parseToDd(`1°27'20.88"S`); // -1.4558, from DD or DMS text; NaN when unreadable
clampLat and clampLng keep typed values in range. Projected coordinates are not handled here; the file stores latitude and longitude only (CRS scope).
Unit labels
| Function | Returns |
|---|---|
resolveFlowUnitLabel(unit) | m³/h, L/s, gpm for the storage tokens m3/h, L/s, gpm. |
resolveVolumeUnitLabel(unit) | m³, L, ft³, gal. |
resolveDiameterUnitLabel(unit, locale) | mm, or " in Portuguese and in. in English for inches. |
Convert the values themselves with the unit conversion helpers of @welldot/core.
Records
formatMeterLabel(meter, { locale, untypedLabel, dateFormat? }):Electromagnetic · S/N 123 · 01/02/2024.permitLabel(permit, fallback?): the authority and identifier of a permit.formatWaterQualityResult(result, labels):< 0.001,0.004 (est.), the not-detected, present or absent label, or the text (Water quality).