上线下线时间转为在线离线时间段

107 阅读2分钟
import dayjs from 'dayjs';

// 生成包括今天在内的过去七天的日期列表
function getFDateList() {
  const dates = [];
  const today = dayjs(); // 获取今天的日期
  for (let i = 0; i <= 6; i++) {
    const date = today.subtract(i, 'day').startOf('day');
    dates.push(date);
  }
  return dates;
}

// 计算两个日期之间的毫秒数差值
function calculateDifference(startDate, endDate) {
  return endDate.diff(startDate);
}

// 将时间差转换为百分比
function calculatePercentage(diff, totalMillis) {
  return (diff / totalMillis) * 100;
}

// 处理数据
function processData(data) {
  // 生成包括今天在内的过去七天的日期列表
  const dateList = getDateList();

  // 获取七天前的日期,即列表中的第一个元素
  const sevenDaysAgo = dateList[0];

  // 获取今天的24点,即列表中的最后一个元素的结束时间
  const today = dayjs(dateList[dateList.length - 1]).endOf('day');

  // 计算从七天前到今天24点的总毫秒数
  const totalMillis = calculateDifference(dayjs(sevenDaysAgo), dayjs(today));

  // 初始化一个数组,用于存放处理过的数据
  const formattedData = [];

  // 设置初始的离线时间为七天前
  let lastOffTime = dayjs(sevenDaysAgo);

 // 遍历传入的数据列表
  data.forEach(item => {
    // 获取每个数据项的上线时间
    const onTime = dayjs(item.on);

    // 获取每个数据项的离线时间,如果不存在则设为null
    const offTime = item.off ? dayjs(item.off) : null;

    // 如果上线时间早于七天前,则设置为七天前的0点
    const startTime = onTime.isBefore(sevenDaysAgo) ? dayjs(sevenDaysAgo) : onTime;

    // 计算离线时长
    if (!lastOffTime.isSame(startTime)) {
      const offlineDiff = calculateDifference(lastOffTime, startTime);
      const offlinePercentage = calculatePercentage(offlineDiff, totalMillis);

      // 添加离线时间段的信息
      formattedData.push({
        name: `${lastOffTime.format('YYYY-MM-DD HH:mm:ss')} - ${startTime.format('YYYY-MM-DD HH:mm:ss')}`,
        width: offlinePercentage,
        type: 'offline'
      });
    }

    // 计算在线时长
    const onlineDiff = offTime ? calculateDifference(startTime, offTime) : calculateDifference(startTime, dayjs());
    const onlinePercentage = calculatePercentage(onlineDiff, totalMillis);

    // 添加在线时间段的信息
    formattedData.push({
      name: `${startTime.format('YYYY-MM-DD HH:mm:ss')} - ${offTime ? offTime.format('YYYY-MM-DD HH:mm:ss') : today.format('YYYY-MM-DD 23:59:59') }`,
      width: onlinePercentage,
      type: 'online'
    });

    lastOffTime = offTime || dayjs();
  });

  // 如果最后一个下线时间是当前时间,则添加剩余的时间作为未知状态
  if (lastOffTime.isSame(dayjs())) {
    const unknownDiff = calculateDifference(lastOffTime, today);
    const unknownPercentage = calculatePercentage(unknownDiff, totalMillis);

    // 添加剩余未知时间段的信息
    formattedData.push({
      name: `${lastOffTime.format('YYYY-MM-DD HH:mm:ss')} - ${today.format('YYYY-MM-DD HH:mm:ss')}`,
      width: unknownPercentage,
      type: 'unknown'
    });
  }
  // 如果最后一个下线时间不是当前时间,则添加下线时间至现在时间为离线状态,剩余的时间作为未知状态
   else{
    const offlineDiff = calculateDifference(lastOffTime, dayjs());
      const offlinePercentage = calculatePercentage(offlineDiff, totalMillis);

      // 添加离线时间段的信息
      formattedData.push({
        name: `${lastOffTime.format('YYYY-MM-DD HH:mm:ss')} - ${dayjs().format('YYYY-MM-DD HH:mm:ss')}`,
        width: offlinePercentage,
        type: 'offline'
      });
      lastOffTime = dayjs()
      const unknownDiff = calculateDifference(lastOffTime, today);
      const unknownPercentage = calculatePercentage(unknownDiff, totalMillis);

      // 添加剩余未知时间段的信息
      formattedData.push({
        name: `${lastOffTime.format('YYYY-MM-DD HH:mm:ss')} - ${today.format('YYYY-MM-DD HH:mm:ss')}`,
        width: unknownPercentage,
        type: 'unknown'
      });
   }
  // 检查总宽度是否为100%
  const totalWidth = formattedData.reduce((acc, item) => acc + item.width, 0);
  if (Math.abs(totalWidth - 100) > Number.EPSILON) {
    throw new Error(`Total width should be 100%, but it is ${totalWidth.toFixed(2)}%`);
  }

  return formattedData;
}

// 测试数据
const testData = [
  { on: '2024-07-25 08:56:26', off: '2024-07-26 18:24:56' },
  { on: '2024-07-29 08:57:26', off: null } // 注意这里的 off 为 null
];

// 调用函数并输出结果
const result = processData(testData);
console.log(result);