Загрузка данных


import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';
import localizedFormat from 'dayjs/plugin/localizedFormat';
import utc from 'dayjs/plugin/utc';

import 'dayjs/locale/ru';

import { TickMarkType, UTCTimestamp } from 'lightweight-charts';

import { TimeFormat, Timeframes } from '@src/types';

// плагины для работы с UTC и локализацией
dayjs.extend(utc);
dayjs.extend(localizedFormat);
dayjs.extend(duration);

export enum DateFormat {
  DOW_Q_YY = 'Mon Q3 \'97',
  DOW_Q_YYYY = 'Mon Q3 1997',
  DOW_D_MMM_YY = 'Mon 29 Sep \'97',
  DOW_MMM_YY = 'Mon Sep \'97',
  DOW_MMM_D_YYYY = 'Mon Sep 29, 1997',
  DOW_MMM_YYYY = 'Mon Sep 1997',
  DOW_MMM_D = 'Mon Sep 29',
  DOW_D_MMM = 'Mon 29 Sep',
  DOW_YYYY_MM_DD_DASH = 'Mon 1997-09-29',
  DOW_YY_MM_DD_DASH = 'Mon 97-09-29',
  DOW_YY_MM_DD_SLASH = 'Mon 97/09/29',
  DOW_YYYY_MM_DD_SLASH = 'Mon 1997/09/29',
  DOW_DD_MM_YYYY_DASH = 'Mon 29-09-1997',
  DOW_DD_MM_YY_DASH = 'Mon 29-09-97',
  DOW_DD_MM_YY_SLASH = 'Mon 29/09/97',
  DOW_DD_MM_YYYY_SLASH = 'Mon 29/09/1997',
  DOW_MM_DD_YY_SLASH = 'Mon 09/29/97',
  DOW_MM_DD_YYYY_SLASH = 'Mon 09/29/1997',
  DD_MM_YYYY_HH_mm_ss = '09.29.1997 00:00:00',
}

export const dateFormatOptions = Object.entries(DateFormat).map(([_, value]) => ({
  label: value,
  value,
}));

const customTimeFormatter = (time: UTCTimestamp, timeFormat: string, locale: string) => {
  const d = dayjs.unix(time).utc().locale(locale);
  if (timeFormat === '12h') {
    return d.format('h:mm:ss A'); // 12-часовой формат
  }
  return d.format('HH:mm:ss'); // 24-часовой формат
};

export function shouldShowTime(tf: Timeframes): boolean {
  return !(tf.endsWith('d') || tf.endsWith('w') || tf.endsWith('M') || tf.endsWith('М') || tf.endsWith('Y'));
}

/**
 * Форматирует UTC timestamp в строку согласно выбранному формату.
 * @param time - UTCTimestamp (секунды)
 * @param format - Значение из enum DateFormat
 * @param timeFormat - Значение из enum TimeFormat
 * @param showTime - Отображать ли время в строке даты
 * @param locale - Языковая локаль (например, 'en-US', 'ru-RU')
 * @returns Отформатированная строка с датой
 */
export function formatDate(
  time: UTCTimestamp,
  format: DateFormat,
  timeFormat: TimeFormat,
  showTime = true,
  locale = 'ru-RU',
): string {
  const d = dayjs.unix(time).utc().locale(locale);

  const findPart = (type: string) => d.format(type);

  let dateString: string;

  switch (format) {
    case DateFormat.DOW_Q_YY: {
      const quarter = Math.floor(d.month() / 3) + 1;
      dateString = `${findPart('ddd')} Q${quarter} '${d.format('YY')}`;
      break;
    }
    case DateFormat.DOW_Q_YYYY: {
      const quarter = Math.floor(d.month() / 3) + 1;
      dateString = `${findPart('ddd')} Q${quarter} ${d.format('YYYY')}`;
      break;
    }
    case DateFormat.DOW_D_MMM_YY:
      dateString = `${findPart('ddd')} ${d.date()} ${d.format('MMM')} '${d.format('YY')}`;
      break;
    case DateFormat.DOW_MMM_YY:
      dateString = `${findPart('ddd')} ${d.format('MMM')} '${d.format('YY')}`;
      break;
    case DateFormat.DOW_MMM_D_YYYY:
      dateString = `${findPart('ddd')} ${d.format('MMM')} ${d.date()}, ${d.format('YYYY')}`;
      break;
    case DateFormat.DOW_MMM_YYYY:
      dateString = `${findPart('ddd')} ${d.format('MMM')} ${d.format('YYYY')}`;
      break;
    case DateFormat.DOW_MMM_D:
      dateString = `${findPart('ddd')} ${d.format('MMM')} ${d.date()}`;
      break;
    case DateFormat.DOW_D_MMM:
      dateString = `${findPart('ddd')} ${d.date()} ${d.format('MMM')}`;
      break;
    case DateFormat.DOW_YYYY_MM_DD_DASH:
      dateString = `${findPart('ddd')} ${d.format('YYYY-MM-DD')}`;
      break;
    case DateFormat.DOW_YY_MM_DD_DASH:
      dateString = `${findPart('ddd')} ${d.format('YY-MM-DD')}`;
      break;
    case DateFormat.DOW_YY_MM_DD_SLASH:
      dateString = `${findPart('ddd')} ${d.format('YY/MM/DD')}`;
      break;
    case DateFormat.DOW_YYYY_MM_DD_SLASH:
      dateString = `${findPart('ddd')} ${d.format('YYYY/MM/DD')}`;
      break;
    case DateFormat.DOW_DD_MM_YYYY_DASH:
      dateString = `${findPart('ddd')} ${d.format('DD-MM-YYYY')}`;
      break;
    case DateFormat.DOW_DD_MM_YY_DASH:
      dateString = `${findPart('ddd')} ${d.format('DD-MM-YY')}`;
      break;
    case DateFormat.DOW_DD_MM_YY_SLASH:
      dateString = `${findPart('ddd')} ${d.format('DD/MM/YY')}`;
      break;
    case DateFormat.DOW_DD_MM_YYYY_SLASH:
      dateString = `${findPart('ddd')} ${d.format('DD/MM/YYYY')}`;
      break;
    case DateFormat.DOW_MM_DD_YY_SLASH:
      dateString = `${findPart('ddd')} ${d.format('MM/DD/YY')}`;
      break;
    case DateFormat.DOW_MM_DD_YYYY_SLASH:
      dateString = `${findPart('ddd')} ${d.format('MM/DD/YYYY')}`;
      break;
    case DateFormat.DD_MM_YYYY_HH_mm_ss:
      dateString = d.format('DD.MM.YYYY');
      break;
    default:
      dateString = `${findPart('ddd')} ${d.format('DD-MM-YYYY')}`;
  }

  if (!showTime) return dateString;

  const timeString = customTimeFormatter(time, timeFormat, locale);
  return `${dateString} ${timeString}`;
}
export function createTickMarkFormatter(
  timeFormatString: string,
  locale = 'ru-RU',
): (time: UTCTimestamp, tickMarkType: TickMarkType) => string {
  return (time, tickMarkType) => {
    const d = dayjs.unix(time).utc().locale(locale);
    switch (tickMarkType) {
      case TickMarkType.Year:
        return d.format('YYYY');
      case TickMarkType.Month:
        return d.format('MMM');
      case TickMarkType.DayOfMonth:
        return d.format('DD');
      case TickMarkType.Time:
        return d.format(timeFormatString);
      default:
        return '';
    }
  };
}

export function formatUtcOffset(date = dayjs()): string {
  const offsetMinutes = date.utcOffset();

  const sign = offsetMinutes >= 0 ? '+' : '-';
  const abs = Math.abs(offsetMinutes);
  const hours = Math.floor(abs / 60);
  const minutes = abs % 60;

  if (minutes === 0) return `${sign}${hours}`;

  return `${sign}${hours}:${String(minutes).padStart(2, '0')}`;
}