[C#] 判斷某個時段有沒有壓到另一個時段
關於時間問題,這我在專案中寫過多次每次寫都要重新考慮一次
這次就索性整理一下,然後就是直接複製貼上,懶得重寫
簡單的說因為常常寫訂單系統,就是有像是家教那樣他假設 12:00~13:00 有課,所以他的客戶不選擇這時段
這時候程式怎麼判斷時段有沒有壓到
先來張示意圖
基本上時間壓到會分成四種狀況 完全涵蓋(藍色),全部在裡面(紅色),壓到開始時間(綠色),壓到結尾時間(咖啡色)
接下來就是我的判斷程式:
public bool IsCoverTimePeoird(DateTime testStart, DateTime testEnd, DateTime baseStart, DateTime baseEnd) | |
{ | |
if (testEnd < testStart) throw new Exception("testEnd Should bigger than testStart"); | |
if (baseEnd < baseStart) throw new Exception("baseEnd Should bigger than baseStart"); | |
//完全涵蓋 | |
if (testStart<baseStart && testEnd>baseEnd) return true; | |
//全部在裡面 | |
if (testStart >= baseStart && testEnd <= baseEnd) return true; | |
//壓到開始時間 | |
if (testStart<=baseStart && testEnd>=baseStart) return true; | |
//if (testStart <= baseStart && testEnd > baseStart) return true; | |
//壓到結束時間 | |
if (testStart <= baseEnd && testEnd >= baseEnd) return true; | |
//if (testStart < baseEnd && testEnd >= baseEnd) return true; | |
return false; | |
} | |
測試部分:
//BaseTime: 12:00~13:00 | |
var baseStart = new DateTime(2023, 01, 01, 12, 0, 0); | |
var baseEnd = new DateTime(2023, 01, 01, 13, 0, 0); | |
Result += "基準時間 12:00~13:00"; | |
Result += "<br>"; | |
Result += "完全涵蓋 11:00~13:01:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 11, 0, 0), | |
new DateTime(2023, 1, 1, 13, 1, 0),baseStart,baseEnd); | |
Result += "<br>"; | |
Result += "全部在裡面 12:20 ~12:21:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 12, 20, 0), | |
new DateTime(2023, 1, 1, 12, 21, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "壓到開始時間 11:20 ~12:20:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 11, 20, 0), | |
new DateTime(2023, 1, 1, 12, 20, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "壓到結尾時間 12:20 ~14:20:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 12, 20, 0), | |
new DateTime(2023, 1, 1, 14, 20, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "完全沒壓到1 11:20~11:59:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 11, 20, 0), | |
new DateTime(2023, 1, 1, 11, minute: 59, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "完全沒壓到2 13:20~14:59:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 13, 20, 0), | |
new DateTime(2023, 1, 1, 14, minute: 59, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "單點判斷開頭 12:00:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 12, 00, 0), | |
new DateTime(2023, 1, 1, 12, minute: 00, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "單點判斷結尾 13:00:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 13, 00, 0), | |
new DateTime(2023, 1, 1, 13, minute: 00, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "判斷一樣 12:00~13:00:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 12, 00, 0), | |
new DateTime(2023, 1, 1, 13, minute: 00, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "判斷剛好壓到頭 11:00~12:00:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 11, 00, 0), | |
new DateTime(2023, 1, 1, 12, minute: 00, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
Result += "判斷剛好壓到尾 13:00~14:00:"; | |
Result += IsCoverTimePeoird(new DateTime(2023, 1, 1, 13, 00, 0), | |
new DateTime(2023, 1, 1, 14, minute: 00, 0), baseStart, baseEnd); | |
Result += "<br>"; | |
結果:
基準時間 12:00~13:00
完全涵蓋 11:00~13:01:True
全部在裡面 12:20 ~12:21:True
壓到開始時間 11:20 ~12:20:True
壓到結尾時間 12:20 ~14:20:True
完全沒壓到1 11:20~11:59:False
完全沒壓到2 13:20~14:59:False
單點判斷開頭 12:00:True
單點判斷結尾 13:00:True
判斷一樣 12:00~13:00:True
判斷剛好壓到頭 11:00~12:00:True
判斷剛好壓到尾 13:00~14:00:True
但是注意有幾件事情要說 判斷剛好壓到頭,這一點在實務上是不合理的
假設有一個客人預約 11:00~12:00 但是你 12:00~13:00 剛好有空,11:00~12:00 應該要為 False 阿
這邊我提供兩個解決方案
1. 將baseStart 跟 baseEnd 加上一秒甚至一毫秒
2. 改寫程式碼中
壓到開始時間 改成
if (testStart <= baseStart && testEnd > baseStart) return true;
壓到結束時間 改成
if (testStart < baseEnd && testEnd >= baseEnd) return true;
這樣結果會變成
基準時間 12:00~13:00
完全涵蓋 11:00~13:01:True
全部在裡面 12:20 ~12:21:True
壓到開始時間 11:20 ~12:20:True
壓到結尾時間 12:20 ~14:20:True
完全沒壓到1 11:20~11:59:False
完全沒壓到2 13:20~14:59:False
單點判斷開頭 12:00:True
單點判斷結尾 13:00:True
判斷一樣 12:00~13:00:True
判斷剛好壓到頭 11:00~12:00:False
判斷剛好壓到尾 13:00~14:00:False
大概寫到這,其實有一個專門的 library ,只是殺雞焉用核子彈我就沒有細讀了,這邊附上連結
https://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET