mirror of
https://github.com/lux-tel/websites.git
synced 2026-10-30 20:31:36 +00:00
115 lines
3.5 KiB
TypeScript
115 lines
3.5 KiB
TypeScript
'use client';
|
|
|
|
import { getDateFromUnixTimestampSeconds } from '@session/util-js/date';
|
|
import {
|
|
type FormatDistanceStrictOptions,
|
|
type FormatDistanceToNowStrictOptions,
|
|
formatDistanceStrict,
|
|
formatDistanceToNowStrict,
|
|
} from 'date-fns';
|
|
import { useLocale as _useLocale } from 'next-intl';
|
|
import { type Locale, getDateFnsLocale } from './locale-util';
|
|
|
|
export const useLocale = _useLocale as () => Locale;
|
|
|
|
export const formatLocalizedRelativeTimeClient = (
|
|
date: Date,
|
|
baseDate: Date,
|
|
options?: Omit<FormatDistanceStrictOptions, 'locale'>
|
|
) => {
|
|
const locale = useLocale();
|
|
return formatDistanceStrict(date, baseDate, {
|
|
locale: getDateFnsLocale(locale),
|
|
...options,
|
|
});
|
|
};
|
|
|
|
export const formatLocalizedRelativeTimeToNowClient = (
|
|
date: Date,
|
|
options?: Omit<FormatDistanceToNowStrictOptions, 'locale'>
|
|
) => {
|
|
const locale = useLocale();
|
|
return formatDistanceToNowStrict(date, {
|
|
locale: getDateFnsLocale(locale),
|
|
...options,
|
|
});
|
|
};
|
|
|
|
export const formatLocalizedTimeFromSeconds = (
|
|
seconds: number,
|
|
options?: Omit<FormatDistanceStrictOptions, 'locale'>
|
|
) =>
|
|
formatLocalizedRelativeTimeClient(getDateFromUnixTimestampSeconds(seconds), new Date(0), options);
|
|
|
|
export const formatNumber = (num: number, options?: Intl.NumberFormatOptions) => {
|
|
return new Intl.NumberFormat(undefined, options).format(num);
|
|
};
|
|
|
|
export const formatUSD = (num: number, options?: Intl.NumberFormatOptions) => {
|
|
const maximumFractionDigits = num >= 0.1 ? 2 : num >= 0.01 ? 3 : 4;
|
|
return formatNumber(num, {
|
|
currency: 'USD',
|
|
style: 'currency',
|
|
currencySign: 'standard',
|
|
maximumFractionDigits: maximumFractionDigits,
|
|
...options,
|
|
});
|
|
};
|
|
|
|
export const formatPercentage = (num: number, options?: Intl.NumberFormatOptions) => {
|
|
return formatNumber(num, {
|
|
style: 'percent',
|
|
minimumFractionDigits: 2,
|
|
maximumFractionDigits: 2,
|
|
...options,
|
|
});
|
|
};
|
|
|
|
export const formatDate = (date: Date, options?: Intl.DateTimeFormatOptions, locale?: Locale) => {
|
|
return new Intl.DateTimeFormat(locale, options).format(date);
|
|
};
|
|
|
|
export const useFormatDate = (
|
|
date?: Date | null,
|
|
options?: Intl.DateTimeFormatOptions,
|
|
fallback?: string | null
|
|
) => {
|
|
const locale = useLocale();
|
|
if (!date) return fallback ?? null;
|
|
return formatDate(date, options, locale);
|
|
};
|
|
|
|
export const formatList = (list: Array<string>, options?: Intl.ListFormatOptions) => {
|
|
const locale = useLocale();
|
|
return new Intl.ListFormat(locale, options).format(list);
|
|
};
|
|
|
|
export type DecimalDelimiter = '.' | ',';
|
|
|
|
export const useDecimalDelimiter = (): DecimalDelimiter => {
|
|
const locale = useLocale();
|
|
const decimal = Intl.NumberFormat(locale)
|
|
.formatToParts(1.1)
|
|
?.find((part) => part.type === 'decimal')?.value;
|
|
if (decimal) return decimal as DecimalDelimiter;
|
|
return (1.1).toLocaleString().substring(1, 2) as DecimalDelimiter;
|
|
};
|
|
|
|
export function formatEnglishTimeDistance(
|
|
seconds: number,
|
|
delimiter = ' ',
|
|
addPluralSuffix = false
|
|
) {
|
|
const days = Math.floor(seconds / 86400);
|
|
if (days > 0) return `${days}${delimiter}day${days > 1 && addPluralSuffix ? 's' : ''}`;
|
|
|
|
const hours = Math.floor((seconds % 86400) / 3600);
|
|
if (hours > 0) return `${hours}${delimiter}hour${hours > 1 && addPluralSuffix ? 's' : ''}`;
|
|
|
|
const minutes = Math.floor((seconds % 3600) / 60);
|
|
if (minutes > 0)
|
|
return `${minutes}${delimiter}minute${minutes > 1 && addPluralSuffix ? 's' : ''}`;
|
|
|
|
return `${Math.floor(seconds)}${delimiter}second${seconds > 1 && addPluralSuffix ? 's' : ''}`;
|
|
}
|