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


function inferTimeStepFromData(data: readonly { time: Time }[]): TimeStep {
  const times = data.reduce<number[]>((acc, item) => {
    if (typeof item.time === 'number' && Number.isFinite(item.time)) {
      acc.push(Number(item.time));
    }

    return acc;
  }, []);

  if (times.length < 2) {
    return createTimeStep('minute', 1, 'inferred:minute:1');
  }

  const uniqueTimes = Array.from(new Set(times)).sort((a, b) => a - b);
  const latestTimes = uniqueTimes.slice(-100);

  const distances: number[] = [];

  for (let index = 1; index < latestTimes.length; index += 1) {
    const prevTime = latestTimes[index - 1];
    const currentTime = latestTimes[index];
    const distance = currentTime - prevTime;

    if (distance > 0) {
      distances.push(distance);
    }
  }

  if (!distances.length) {
    return createTimeStep('minute', 1, 'inferred:minute:1');
  }

  distances.sort((a, b) => a - b);

  const medianDistance = distances[Math.floor(distances.length / 2)];

  if (medianDistance < 60) {
    const amount = Math.max(1, Math.round(medianDistance));

    return createTimeStep('second', amount, `inferred:second:${amount}`);
  }

  if (medianDistance < 3600) {
    const amount = Math.max(1, Math.round(medianDistance / 60));

    return createTimeStep('minute', amount, `inferred:minute:${amount}`);
  }

  if (medianDistance < DAY_SECONDS) {
    const amount = Math.max(1, Math.round(medianDistance / 3600));

    return createTimeStep('hour', amount, `inferred:hour:${amount}`);
  }

  if (medianDistance < DAY_SECONDS * 27) {
    const amount = Math.max(1, Math.round(medianDistance / DAY_SECONDS));

    return createTimeStep('day', amount, `inferred:day:${amount}`);
  }

  if (medianDistance < DAY_SECONDS * 90) {
    const amount = Math.max(1, Math.round(medianDistance / (DAY_SECONDS * 30)));

    return createTimeStep('month', amount, `inferred:month:${amount}`);
  }

  if (medianDistance < DAY_SECONDS * 365) {
    const amount = Math.max(1, Math.round(medianDistance / (DAY_SECONDS * 7)));

    return createTimeStep('week', amount, `inferred:week:${amount}`);
  }

  const amount = Math.max(1, Math.round(medianDistance / (DAY_SECONDS * 365)));

  return createTimeStep('year', amount, `inferred:year:${amount}`);
}