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}`; } const snapshotFormatter = new Intl.DateTimeFormat("ru-RU", { dateStyle: "short", timeStyle: "short", timeZone: "UTC", }); 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, };