brestok's picture
fix date
bf4edb5
Raw History Blame Contribute Delete
2.94 kB
const money = new Intl.NumberFormat('en-GB', {
style: 'currency',
currency: 'EUR',
maximumFractionDigits: 0,
});
const decimal = new Intl.NumberFormat('en-GB', { maximumFractionDigits: 1 });
export const formatMoney = (value: number): string => money.format(value);
export const formatDecimal = (value: number): string => decimal.format(value);
/** A shipment carries its own currency, so the symbol is not assumed to be €. */
export function formatAmount(value: number, currency: string): string {
try {
return new Intl.NumberFormat('en-GB', {
style: 'currency',
currency,
maximumFractionDigits: 2,
}).format(value);
} catch {
return `${formatNumber(value)} ${currency}`;
}
}
export function formatNumber(value: number, maximumFractionDigits = 2): string {
return new Intl.NumberFormat('en-GB', { maximumFractionDigits }).format(value);
}
/** The backend already scores out of 100 β€” `recompute.py` multiplies by 100.0. */
export const formatScore = (score: number): string => `${formatNumber(score, 1)}%`;
/** `2026-09-22` as `22.09.2026`; anything unparseable is returned untouched. */
export function formatDate(value: string | null | undefined): string {
if (!value) return 'β€”';
const match = /^(\d{4})-(\d{2})-(\d{2})/.exec(value);
return match ? `${match[3]}.${match[2]}.${match[1]}` : value;
}
/** `22.09.2026` (or with `/` or `-`) as `2026-09-22`; null unless it is a real day. */
export function parseDate(text: string): string | null {
const match = /^(\d{1,2})[./-](\d{1,2})[./-](\d{4})$/.exec(text.trim());
if (!match) return null;
const [day, month, year] = [Number(match[1]), Number(match[2]), Number(match[3])];
const date = new Date(year, month - 1, day);
if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
return null;
}
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
}
/** The local calendar day β€” `toISOString` would give the UTC one, which in
* Europe is still yesterday for the first hour or two after midnight. */
export function today(): string {
const now = new Date();
return [
now.getFullYear(),
String(now.getMonth() + 1).padStart(2, '0'),
String(now.getDate()).padStart(2, '0'),
].join('-');
}
/** The same rule as `normalize_header` in `importer/utils.py`, so a column
* header matches here exactly when it matches on the server. */
export const normalizeHeader = (value: string): string =>
value.trim().toLowerCase().replace(/[^a-z0-9]/g, '');
/** `6109100010` as `6109 10 00 10`, the way a declarant reads it. */
export function formatCode(code: string | null | undefined): string {
if (!code) return '';
const digits = code.replace(/\D/g, '');
if (digits.length < 6) return code;
return [digits.slice(0, 4), digits.slice(4, 6), digits.slice(6, 8), digits.slice(8, 10)]
.filter(Boolean)
.join(' ');
}