2013-01-02 159 views
2

假設夜間時間設定爲20.30h至6.15h(上午)。這2個參數是用戶範圍的變量。 假設您的到達日期和出發日期可以從幾分鐘到一天以上。 你如何計算夜間總時數?編輯:我知道這可能不是直截了當的yes/no的答案,但也許有人有這個問題的優雅的解決方案。 要回答評論:我的確希望計算落在用戶可編輯的夜間開始時間和結束時間之間的總小時數(或分鐘數)。我正在計算訪問時間,第一個日期確實是到達參數。計算時間範圍內的總夜間時間

的代碼我有SOFAR:

DateTime nightStart = new DateTime(departure.Year, departure.Month, departure.Day, 
            nightTimeStartHour, nightTimeStartMinute, 0); 
DateTime nightEnd = new DateTime(arrival.Year, arrival.Month, arrival.Day, 
            nightTimeEndHour, nightTimeEndMinute, 0); 
if (arrival < nightEnd) 
{ 
    decimal totalHoursNight = (decimal)nightEnd.Subtract(arrival).TotalHours; 
} 
//... 
+1

所以你想知道他們的旅行時間有多少是在晚上完成的? –

+8

這似乎是一個相當微不足道的問題(可能有些乏味),除非您有更具體的問題或有代碼表明您已經嘗試過,否則這些問題並不是很多人願意爲您做的。 –

+1

哪個是第一次約會?到達還是離開?即你計算旅行時間還是訪問時間? – musefan

回答

5

只是因爲我是爲你應該可以使用下面的函數成功的挑戰。請注意,這可能不是最有效的方式,但我這樣做,所以我可以佈置邏輯。我可能會決定將其作爲改進它的一點,但它應該按原樣運行。

同樣重要的是要注意的幾個假設的位置:

  1. 的「結束」參數總是比「開始」參數大(儘管我們檢查反正第一件事)
  2. 夜結束參數比夜間啓動參數早(即夜間時間在第二天結束,但從未多達24小時後)
  3. 夏時制不存在! (這是一個棘手的問題,需要解決的一個重要問題是:如果你的開始或結束時間是在時鐘返回的那一天的01:30,那麼如何知道在回滾之前還是之後記錄了時間?它是第一或第二次時鐘已經達到01:30)

考慮到這一點......

public static double Calc(DateTime start, DateTime end, int startHour, int startMin, int endHour, int endMin) 
{ 
    if (start > end) 
     throw new Exception();//or whatever you want to do 

    //create timespans for night hours 
    TimeSpan nightStart = new TimeSpan(startHour, startMin, 0); 
    TimeSpan nightEnd = new TimeSpan(endHour, endMin, 0); 

    //check to see if any overlapping actually happens 
    if (start.Date == end.Date && start.TimeOfDay >= nightEnd && end.TimeOfDay <= nightStart) 
    { 
     //no overlapping occurs so return 0 
     return 0; 
    } 

    //check if same day as will process this differently 
    if (start.Date == end.Date) 
    { 
     if (start.TimeOfDay > nightStart || end.TimeOfDay < nightEnd) 
     { 
      return (end - start).TotalHours; 
     } 

     double total = 0; 
     if (start.TimeOfDay < nightEnd) 
     { 
      total += (nightEnd - start.TimeOfDay).TotalHours; 
     } 
     if(end.TimeOfDay > nightStart) 
     { 
      total += (end.TimeOfDay - nightStart).TotalHours; 
     } 
     return total; 
    } 
    else//spans multiple days 
    { 
     double total = 0; 

     //add up first day 
     if (start.TimeOfDay < nightEnd) 
     { 
      total += (nightEnd - start.TimeOfDay).TotalHours; 
     } 
     if (start.TimeOfDay < nightStart) 
     { 
      total += ((new TimeSpan(24, 0, 0)) - nightStart).TotalHours; 
     } 
     else 
     { 
      total += ((new TimeSpan(24, 0, 0)) - start.TimeOfDay).TotalHours; 
     } 

     //add up the last day 
     if (end.TimeOfDay > nightStart) 
     { 
      total += (end.TimeOfDay - nightStart).TotalHours; 
     } 
     if (end.TimeOfDay > nightEnd) 
     { 
      total += nightEnd.TotalHours; 
     } 
     else 
     { 
      total += end.TimeOfDay.TotalHours; 
     } 

     //add up any full days 
     int numberOfFullDays = (end - start).Days; 
     if (end.TimeOfDay > start.TimeOfDay) 
     { 
      numberOfFullDays--; 
     } 
     if (numberOfFullDays > 0) 
     { 
      double hoursInFullDay = ((new TimeSpan(24, 0, 0)) - nightStart).TotalHours + nightEnd.TotalHours; 
      total += hoursInFullDay * numberOfFullDays; 
     } 

     return total; 
    } 
} 

然後,您可以調用它是這樣的:?

double result = Calc(startDateTime, endDateTime, 20, 30, 6, 15); 
+2

重疊測試可以簡單地:'開始。 Date == end.Date && start.TimeOfDay> = nightEnd && end.TimeOfDay <= nightStart',因爲'start <= end'。 –

+1

@ OlivierJacot-Descombes:謝謝,編輯 – musefan

+0

謝謝musefan! –

2

基本上你會想要計算當夜晚開始和結束。然後將這些數據與抵達和離開日期進行比較,以查看您是否在晚上開始或離開之前抵達,以便獲取需要減去的值以確定總的夜間時間。然後,您需要繼續計算每天的計算時間,直到夜間的開始時間超過出發日期。這是我的解決方案。

public static double CalculateTotalNightTimeHours(
    DateTime arrival, 
    DateTime departure, 
    int nightTimeStartHour, 
    int nightTimeStartMinute, 
    int nightTimeEndHour, 
    int nightTimeEndMinute) 
{ 
    if (arrival >= departure) 
     return 0; 

    var nightStart = arrival.Date.AddHours(nightTimeStartHour).AddMinutes(nightTimeStartMinute); 
    var nightEnd = nightStart.Date.AddDays(1).AddHours(nightTimeEndHour).AddMinutes(nightTimeEndMinute); 

    double nightHours = 0; 
    while (departure > nightStart) 
    { 
     if (nightStart < arrival) 
      nightStart = arrival; 
     if (departure < nightEnd) 
      nightEnd = departure; 
     nightHours += (nightEnd - nightStart).TotalHours; 
     nightStart = nightStart.Date.AddDays(1).AddHours(nightTimeStartHour).AddMinutes(nightTimeStartMinute); 
     nightEnd = nightStart.Date.AddDays(1).AddHours(nightTimeEndHour).AddMinutes(nightTimeEndMinute); 
    } 

    return nightHours; 
} 

您可能還想添加檢查以確保開始和結束小時數在範圍內。這也假定夜晚開始於一天,結束於下一天,所以如果你想在夜晚之前結束夜晚,你必須做其他事情。

+1

夏時制呢? – Alan

+0

@Alan這不處理夏令時。 – juharr

+0

感謝您的回答juharr。自從首次發佈後我接受了其他答案。 –