JS實現檢查給定時間範圍是否在每天的某個時間段內

﹏王蘑菇~發表於2024-04-03
// 解析時間字串,返回對應的分鐘數
function parseTime(timeStr) {
    const [hours, minutes] = timeStr.split(':').map(num => parseInt(num));
    return hours * 60 + minutes;
}

// 解析時間字串,返回對應的 Date 物件
function parseTimeString(timeStr) {
    const match = timeStr.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})$/);
    if (!match) {
        return null;
    }
    const year = parseInt(match[1]);
    const month = parseInt(match[2]) - 1; // 月份從 0 開始
    const day = parseInt(match[3]);
    const hour = parseInt(match[4]);
    const minute = parseInt(match[5]);
    return new Date(year, month, day, hour, minute);
}

function isOverlapWithProhibitedRanges(startTimeStr, endTimeStr, prohibitedRanges) {
    const startTime = parseTimeString(startTimeStr);
    const endTime = parseTimeString(endTimeStr);

    if (!startTime || !endTime) {
        return false;
    }

    const startDay = startTime.getDay();
    const endDay = endTime.getDay();

    if (startDay === endDay) {
        const startHour = startTime.getHours();
        const startMinute = startTime.getMinutes();
        const endHour = endTime.getHours();
        const endMinute = endTime.getMinutes();

        const startMinutes = startHour * 60 + startMinute;
        const endMinutes = endHour * 60 + endMinute;
        const prohibitedRange = prohibitedRanges[startDay];

        if (prohibitedRange && !(endMinutes <= parseTime(prohibitedRange.start) || startMinutes >= parseTime(prohibitedRange.end))) {
            return true;
        }
    } else {
        let currentDate = new Date(startTime);
        while (currentDate.getDay() !== endDay) {
            const currentDay = currentDate.getDay();
            const currentDayProhibitedRange = prohibitedRanges[currentDay];
            const startHour = currentDate.getHours();
            const startMinute = currentDate.getMinutes();
            const endHour = 23;
            const endMinute = 59;

            const startMinutes = startHour * 60 + startMinute;
            const endMinutes = endHour * 60 + endMinute;

            if (currentDayProhibitedRange && !(endMinutes <= parseTime(currentDayProhibitedRange.start) || startMinutes >= parseTime(currentDayProhibitedRange.end))) {
                return true;
            }

            currentDate.setDate(currentDate.getDate() + 1);
            currentDate.setHours(0, 0, 0, 0);
        }

        const currentDay = currentDate.getDay();
        const currentDayProhibitedRange = prohibitedRanges[currentDay];
        const startHour = currentDate.getHours();
        const startMinute = currentDate.getMinutes();
        const endHour = endTime.getHours();
        const endMinute = endTime.getMinutes();

        const startMinutes = startHour * 60 + startMinute;
        const endMinutes = endHour * 60 + endMinute;

        if (currentDayProhibitedRange && !(endMinutes <= parseTime(currentDayProhibitedRange.start) || startMinutes >= parseTime(currentDayProhibitedRange.end))) {
            return true;
        }
    }

    return false;
}

// 示例用法
const startTime = "2024-04-06 03:00";
const endTime = "2024-04-06 04:01";

const prohibitedRanges = [
    { start: "10:00", end: "22:00" }, // 週日
    { start: "08:00", end: "20:00" }, // 週一
    { start: "08:00", end: "20:00" }, // 週二
    { start: "08:00", end: "20:00" }, // 週三
    { start: "08:00", end: "20:00" }, // 週四
    { start: "08:00", end: "20:00" }, // 週五
    { start: "10:00", end: "22:00" }  // 週六
];

function test123(startTime, endTime, prohibitedRanges){
	if (isOverlapWithProhibitedRanges(startTime, endTime, prohibitedRanges)) {
		console.log("給定的時間範圍與禁止的時間範圍有重合。");
		console.log("Fail");
	} else {
		console.log("給定的時間範圍與禁止的時間範圍沒有重合。");
		console.log("Pass");
	}
}
test123("2024-04-06 03:00", "2024-04-06 04:01", prohibitedRanges);//週六,Pass
test123("2024-04-06 10:00", "2024-04-06 20:00", prohibitedRanges);//週六,Fail
test123("2024-04-05 03:00", "2024-04-05 04:01", prohibitedRanges);//週五,Pass
test123("2024-04-05 10:00", "2024-04-05 20:00", prohibitedRanges);//週五,Fail
test123("2024-04-05 10:00", "2024-04-06 20:00", prohibitedRanges);//跨天,Fail
test123("2024-04-05 10:00", "2024-04-08 20:00", prohibitedRanges);//跨天,Fail


function convertTimezone(schedule, offset) {
    // 函式用於將時間從一個時區轉換到另一個時區
    function convertTime(time, offset) {
        const [hour, minute] = time.split(':').map(Number);
        let totalMinutes = hour * 60 + minute;
        totalMinutes += offset * 60; // 將小時偏移轉換為分鐘偏移
        if (totalMinutes < 0) {
            totalMinutes += 24 * 60;
        } else if (totalMinutes >= 24 * 60) {
            totalMinutes -= 24 * 60;
        }
        const newHour = Math.floor(totalMinutes / 60) % 24;
        const newMinute = (totalMinutes % 60).toString().padStart(2, '0');
        return `${newHour.toString().padStart(2, '0')}:${newMinute}`;
    }

    // 遍歷每一天的時間段,進行時區轉換
    const convertedSchedule = schedule.map((timeSlot, index) => {
        const start = convertTime(timeSlot.start, offset);
        const end = convertTime(timeSlot.end, offset);
        return { start, end, weekday: index };
    });

    return convertedSchedule;
}

// 示例用法
const schedule = [
    { start: "10:00", end: "22:00" }, // 週日
    { start: "08:00", end: "20:00" }, // 週一
    { start: "08:00", end: "20:00" }, // 週二
    { start: "08:00", end: "20:00" }, // 週三
    { start: "08:00", end: "20:00" }, // 週四
    { start: "08:00", end: "20:00" }, // 週五
    { start: "10:00", end: "22:00" }  // 週六
];

const convertedSchedule = convertTimezone(schedule, -8.5); // 例如,偏移量 +5 表示向後調整5小時
console.log(convertedSchedule);

相關文章