Files
frontend/src/shared/lib/display.ts
T

98 lines
2.3 KiB
TypeScript

const DECIMAL_PART_COUNT = 2;
const CENTS_PRECISION = 2;
type FormatMoneyOptions = {
withZeroCents?: boolean;
};
type Money = { currency: string; value: string };
const dateFormatter = new Intl.DateTimeFormat("ru-RU", {
day: "2-digit",
month: "2-digit",
timeZone: "UTC",
year: "numeric",
});
function formatDate(value: string): string {
return dateFormatter.format(new Date(value));
}
function formatDecimal(value: string): string {
const [integer = "", fraction] = value.split(".", DECIMAL_PART_COUNT);
const sign = integer.startsWith("-") ? "-" : "";
const digits = sign ? integer.slice(1) : integer;
const groupSize = 3;
const groups: string[] = [];
for (let end = digits.length; end > 0; end -= groupSize) {
groups.push(digits.slice(Math.max(0, end - groupSize), end));
}
const grouped = groups.toReversed().join(" ");
const suffix = fraction ? `,${fraction}` : "";
return `${sign}${grouped}${suffix}`;
}
function formatMoney(
money: Money
| null
| undefined,
{ withZeroCents = false }: FormatMoneyOptions = {},
): string {
if (!money) return "—";
const [integerPart = "", fractionPart = ""] = money.value.split(
".",
DECIMAL_PART_COUNT,
);
const normalizedFraction = withZeroCents
? fractionPart.padEnd(CENTS_PRECISION, "0")
: fractionPart;
const decimal = normalizedFraction
? `${integerPart}.${normalizedFraction}`
: integerPart;
const currency = money.currency === "RUB" ? "₽" : money.currency;
return `${formatDecimal(decimal)} ${currency}`;
}
// Без timeZone Intl берёт часовой пояс браузера пользователя.
const snapshotFormatter = new Intl.DateTimeFormat("ru-RU", {
dateStyle: "short",
timeStyle: "short",
});
function formatSnapshotTime(value: string): string {
return snapshotFormatter.format(new Date(value));
}
const logoSize = 160;
const chartFormatter = new Intl.NumberFormat("ru-RU", { maximumFractionDigits: 4 });
function formatChartValue(value: number) {
return chartFormatter.format(value);
}
function instrumentLogoUrl(logoName?: null | string): null | string {
const stem = logoName?.trim().replace(/\.png$/i, "");
return stem
? `https://invest-brands.cdn-tinkoff.ru/${stem}x${logoSize}.png`
: null;
}
export {
formatChartValue,
formatDate,
formatDecimal,
formatMoney,
formatSnapshotTime,
instrumentLogoUrl,
};