31 lines
1.1 KiB
TypeScript
31 lines
1.1 KiB
TypeScript
/**
|
|
* Swiss accounting number format: #'##0.00
|
|
* Apostrophe as thousands separator, dot as decimal, always 2 decimals.
|
|
*
|
|
* Examples: 1'234.56 | -50.00 | 0.00 | 12'345'678.90
|
|
*
|
|
* @param dashOnZero If true, return "—" when the value is 0.
|
|
*/
|
|
export const formatAmount = (value: unknown, dashOnZero = false): string => {
|
|
const num = typeof value === 'number' ? value : parseFloat(String(value));
|
|
if (isNaN(num)) return '—';
|
|
if (dashOnZero && num === 0) return '—';
|
|
|
|
const isNegative = num < 0;
|
|
const [intPart, decPart] = Math.abs(num).toFixed(2).split('.');
|
|
const grouped = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, "'");
|
|
|
|
return `${isNegative ? '-' : ''}${grouped}.${decPart}`;
|
|
};
|
|
|
|
/**
|
|
* Format a percentage value with 2 decimals (no thousands separator).
|
|
* Returns "—" when the value is 0, null, undefined or NaN.
|
|
*
|
|
* Examples: 7.70% | 19.00% | — (for 0)
|
|
*/
|
|
export const formatPercent = (value: unknown): string => {
|
|
const num = typeof value === 'number' ? value : parseFloat(String(value));
|
|
if (isNaN(num) || num === 0) return '—';
|
|
return `${num.toFixed(2)}%`;
|
|
};
|