66 lines
1.6 KiB
TypeScript
66 lines
1.6 KiB
TypeScript
type Money = { currency: string; value: string };
|
|
type FormatMoneyOptions = {
|
|
withZeroCents?: boolean;
|
|
};
|
|
|
|
function formatDecimal(value: string): string {
|
|
const [integer, fraction] = value.split(".");
|
|
const sign = integer.startsWith("-") ? "-" : "";
|
|
const grouped = (sign ? integer.slice(1) : integer).replace(
|
|
/\B(?=(\d{3})+(?!\d))/g,
|
|
" ",
|
|
);
|
|
return `${sign}${grouped}${fraction ? `,${fraction}` : ""}`;
|
|
}
|
|
|
|
function formatMoney(
|
|
money: Money | null,
|
|
{ withZeroCents = false }: FormatMoneyOptions = {},
|
|
): string {
|
|
if (!money) return "—";
|
|
const [integerPart, fractionPart = ""] = money.value.split(".");
|
|
const normalizedFraction =
|
|
withZeroCents && !fractionPart
|
|
? "00"
|
|
: withZeroCents && fractionPart.length === 1
|
|
? `${fractionPart}0`
|
|
: fractionPart;
|
|
return `${formatDecimal(
|
|
`${integerPart}${normalizedFraction ? `.${normalizedFraction}` : ""}`,
|
|
)} ${money.currency === "RUB" ? "₽" : money.currency}`;
|
|
}
|
|
|
|
function formatDate(value: string): string {
|
|
return new Intl.DateTimeFormat("ru-RU", {
|
|
day: "2-digit",
|
|
month: "2-digit",
|
|
year: "numeric",
|
|
timeZone: "UTC",
|
|
}).format(new Date(value));
|
|
}
|
|
|
|
function formatSnapshotTime(value: string): string {
|
|
return new Intl.DateTimeFormat("ru-RU", {
|
|
dateStyle: "short",
|
|
timeStyle: "short",
|
|
timeZone: "UTC",
|
|
}).format(new Date(value));
|
|
}
|
|
|
|
const logoSize = 160;
|
|
|
|
function instrumentLogoUrl(logoName: string | null | undefined): string | null {
|
|
const stem = logoName?.trim().replace(/\.png$/i, "");
|
|
return stem
|
|
? `https://invest-brands.cdn-tinkoff.ru/${stem}x${logoSize}.png`
|
|
: null;
|
|
}
|
|
|
|
export {
|
|
formatDate,
|
|
formatDecimal,
|
|
formatMoney,
|
|
formatSnapshotTime,
|
|
instrumentLogoUrl,
|
|
};
|