JS不靠譜系列之枚舉出時間段和對應的分鐘數

前言

今天遇到一個需求,是把選擇時間段轉爲分鐘數提交上去的; 因此想手動寫個數組一一映射,提交的時候遍歷下匹配的值提交.javascript

好比 : 00:000分鐘或者1440分鐘; 00:1030分鐘;java

具體看下面的git

  • 2017-8-17 : 加入遍歷功能呢
參數: 
 value : string || Array
 type : 'formatTime' || 'number'
 返回:
 string || Array
複製代碼

效果圖

這裏寫圖片描述

實現思路及功能

思路

  1. 一天的分數很容易換算出來: 24 * 60 = 14400;
  2. 字符串拼接要用到求餘,還有小於10補0;

功能

  • 能夠切割任何週期分數(能夠整除的數值),好比5,10,30,60這種分鐘週期
  • 默認週期30分鐘

你能拿來幹啥!github

  • 寫一個時間段選擇的組件,固然這裏只是單純拿值

代碼實現

// 枚舉出分鐘
export function enumTime(step=30) {
  let temp = []; // 儲存結果集
  let alLCount = 86400 / 60 / step;
  let hourCount = 60 / step;
  let hour = 0; // 小時
  let minute = 0; // 小時內的分鐘

  for (let i = 0; i < alLCount; i++) {
    if (i === 0 && hour === 0) {
      temp.push({
        text: "00:00",
        value: step * i
      });
    } else {
      if (step * i % 60 === 0) {
        minute = 0;
        hour = hour + 1;
      } else {
        minute = step * i % 60;
      }
      minute = minute < 10 ? "0" + minute : minute;
      temp.push({
        text:
          parseInt(hour, 10) < 10
            ? "0" + hour + ":" + minute
            : hour + ":" + minute,
        value: step * i
      });
    }
  }
  return temp;
  console.log(temp);
}
複製代碼
  • 遍歷功能
function enumHourTime(value, type = "formatTime") {
  const TimeList = ((step = 30) => {
    let temp = []; // 儲存結果集
    let alLCount = 86400 / 60 / step;
    let hour = 0; // 小時
    let minute = 0; // 小時內的分鐘

    for (let i = 0; i < alLCount; i++) {
      if (i === 0 && hour === 0) {
        temp.push({
          formatTime: "00:00",
          number: "" + step * i
        });
      } else {
        if (step * i % 60 === 0) {
          minute = 0;
          hour = hour + 1;
        } else {
          minute = step * i % 60;
        }
        minute = minute < 10 ? "0" + minute : minute;
        temp.push({
          formatTime:
            parseInt(hour, 10) < 10
              ? "0" + hour + ":" + minute
              : hour + ":" + minute,
          number: "" + step * i
        });
      }
    }
    return temp;
  })();

  function searchValue(value, type) {
    for (let i = 0, j = TimeList.length; i < j; i++) {
      if (type === "formatTime") {
        if (TimeList[i][type] === value) {
          return TimeList[i]["number"];
        }
      }
      if (type === "number") {
        if (TimeList[i][type] === value) {
          return TimeList[i]["formatTime"];
        }
      }
    }
  }

  if (Array.isArray(value)) {
    return value.map(item => {
      console.log(item);
      return searchValue(item, type);
    });
    return tempArr;
  } else {
    return searchValue(value, type);
  }
}
複製代碼

效果圖數組

這裏寫圖片描述

問題答疑

Q: JS時間分段

給定一個時間段和步長,枚舉該時間段內步長的劃分 例如:時間段3:00-5:00,步長爲20分鐘 那麼返回的數組爲 ['3:00-3:20', '3:20-3:40'....]bash

這類問題,通常都要先梳理好思路再來寫。函數

  • 給定字符串時間段,切割,轉換爲分鐘
  • 跨日及跨時問題
// 這個東東個人小夥伴也寫出來了.個人是在它的解答方式上加以註釋和對參數的判斷作了考慮
// 他的解法方案在他的 github 上 https://github.com/lyh2668/blog/issues/1 , by lyh2668
// 方便一些小夥伴的理解,如下代碼包含ES6的姿式(參數默認值,剪頭函數)

let inputDateRange = (date, step = 30, separator = '-') => {
  let startTime, endTime; // 開始時間和結束時間

  if (Object.prototype.toString.call(date) === '[object String]') {
    date = date.trim(); // 去除兩邊的空格
    var tempDate = '';
    if (separator) {
      tempDate = date.split(separator);
    } else {
      if (date.indexOf('-') !== -1) {
        tempDate = date.split('-');
      } else if (date.indexOf('~')) {
        tempDate = date.split('~');
      } else {
        console.log('您傳入的也許不是一個時間段!!!');
      }
    }
    startTime = time2min(tempDate[0]); // 傳入的開始時間
    endTime = time2min(tempDate[1]); //傳入的結束時間
  } else if (Object.prototype.toString.call(date) === '[object Array]') {
    if (date.length === 2) {
      startTime = time2min(date[0]); // 傳入的開始時間
      endTime = time2min(date[1]); //傳入的結束時間
    }
  } else {
    console.log('您傳入的也許不是一個時間段!!!');
  }

  // 傳入的 step 是否爲數字,不然截圖數字部分轉化
  // 爲何和 NaN 比較(自身不等性),如果傳入的連正則都無法識別,那隻能給默認值了
  Object.prototype.toString.call(step) === '[object Number]'
    ? (step = parseInt(step, 10))
    : parseInt(step.replace(/[W\s\b]/g, ''), 10) === NaN
      ? (step = parseInt(step.replace(/[W\s\b]/g, ''), 10))
      : (step = 30);

  // 如果開始時間大於結束時間則結束時間日後追加一天
  startTime > endTime ? (endTime += 24 * 60) : '';

  let transformDate = []; // 儲存轉換後的數組,時間分段

  // 開始遍歷判斷,用 while
  while (startTime < endTime) {
    // 若是開始時間+步長大於結束時間,則這個分段結束,不然結束時間是步長遞增
    let right = startTime + step > endTime ? endTime : startTime + step;
    transformDate.push(`${min2time(startTime)}-${min2time(right)}`);
    startTime += step; // 步長遞增
  }
  return transformDate;
};

// 時間轉化爲分鐘
let time2min = time => {
  // 獲取切割的
  time.indexOf(':') ? (time = time.trim().split(':')) : '';
  return time[0] * 60 + parseInt(time[1]); // 返回轉化的分鐘
};

// 分鐘轉會字符串時間
let min2time = minutes => {
  let hour = parseInt(minutes / 60); // 返回多少小時
  let minute = minutes - hour * 60; // 扣除小時後剩餘的分鐘數

  hour >= 24 ? (hour = hour - 24) : ''; // 如果大於等於24小時須要扣除一天獲得所剩下的小時
  minute < 10 ? (minute = '0' + minute) : ''; // 小於10的都要補零
  hour < 10 ? (hour = '0' + hour) : ''; // 小於10的都要補零
  return `${hour}:${minute}`;
};


// test ,支持字符串傳入時間段
inputDateRange('3:00-5:00','20d'); // ["03:00-03:20", "03:20-03:40", "03:40-04:00", "04:00-04:20", "04:20-04:40", "04:40-05:00"]

// 亦或者數組傳入
inputDateRange(['3:00','5:00'],'45df.3d'); // ["03:00-03:45", "03:45-04:30", "04:30-05:00"]

// step 支持數字亦或者帶特殊字符的數字
inputDateRange(['6:00','8:00'],'55df.3d'); // ["06:00-06:55", "06:55-07:50", "07:50-08:00"]

inputDateRange('3:00-5:00',60); // ["03:00-04:00", "04:00-05:00"]


複製代碼

總結

原本想寫個支持週期(24小時或者12小時),分析了下改動應該挺多的..ui

我這邊不須要這些,保持代碼簡潔就沒增長進去了,有興趣的能夠進一步封裝成一個選擇時間段的組件。spa

沒什麼特別的難度,只是單純的當作備忘錄丟出來,也許有小夥伴恰好要用到呢!!prototype

相關文章
相關標籤/搜索