2008-10-05 132 views
2

這是我永遠無法工作的一件事。
我的問題是要檢測一天的結束和下一個的開始,然後將diff分解爲每一天。計算午夜時間差異

想象一下,您想計算一個工資率,但它必須跨越午夜。

它也適用於計算在定時系統上運行的時間或它應該運行的時間差。

+0

在計算工資率時,通常只考慮工作時間,考慮到酒店職員從晚上10點開始工作到上午6點,他仍然工作8小時,即使他的工作時間跨度爲兩天 – CheGueVerra 2008-10-05 21:58:26

+0

確實,但如果費率從一天到另一天不同,你應該用另一個乘數來計算一些小時數。 – 2008-10-05 22:21:52

回答

7

這顯然是在其中起始和結束時間是包含日期和時間的數據結構的系統一個微不足道的問題。但是有很多系統不這樣做。計時系統具有包含日期​​,開始時間和結束時間的單個記錄是非常常見的。在這種情況下,問題並不重要。

還有,我認爲,有兩個問題你問:

  1. 我如何判斷一個時間跨度跨越午夜?
  2. 如果一個時間跨度是午夜,第一天發生了多少時間,第二天發生了多少時間?

第一個問題很容易回答:如果結束時間在開始時間之前,則時間跨度超過午夜。

如果是這樣,那麼你有兩個數量來計算。在該日期發生的時間跨度是從開始時間到午夜之間的時間。在下一個日期發生的時間跨度是午夜到結束時間之間的時間(即僅僅是結束時間)。

8

我更願意記錄Unix紀元時刻,這樣它的那樣簡單

hoursWorked = ((stopTime - startTime)/60)/60 

這裏是一個完整的解決方案是在PHP,但應該是很容易建立,以任何語言:

<?php 
$startTime = "12/31/2008 22:02"; //No AM/PM we'll use 24hour system 
$endTime = "01/01/2009 06:27"; //Again no AM/PM and we spaned the midnight time gap. 
/* 
Use this to test for a normal shift not ocurring durring midnight. 
$startTime = "01/01/2008 06:02"; //No AM/PM we'll use 24hour system 
$endTime = "01/01/2008 14:27"; //Again no AM/PM and we spaned the midnight time gap. 
*/ 
$startTime = split(' ', $startTime); 
$endTime = split(' ', $endTime); 
$startTime[1] = split(':', $startTime[1]); 
$endTime[1] = split(':', $endTime[1]); 
/* 
$startTime[0] contains the date 
$startTime[1][0] contains the hours 
$startTime[1][1] contains the minutes 
same is true for endTime 
*/ 
if($startTime[0] != $endTime[0]) 
{ 
    if(date2epoch($endTime[0]) > date2epoch($startTime[0])) 
    { 
     $minutesWorked1 = (59 - $startTime[1][1]); //Calculate how many minutes have occured from begining of shift to midnight 
     $minutesWorked2 = $endTime[1][1]; //Number of minute from midnight to end of shift 
     $hoursWorked1 = (23 - $startTime[1][0]);//Number of hours from start of shift to midnight 
     $hoursWorked2 = $endTime[1][0];//Number of minutes from midnight to end of shift 
     echo 'Before midnight you worked ' . $hoursWorked1 . ':' . $minutesWorked1 . "\nAfter midnight you worked " . $hoursWorked2 . ':' . $minutesWorked2 . '.'; 
    } 
    else 
    { 
     //SOMETHING MAJOR BAD HAS HAPPENED WHILE LOGGING THE CLOCKINS AND CLOCKOUTS 
    } 
} 
else 
{ 
    echo 'Today you worked ' . ($endTime[1][0] - $startTime[1][0]) . ':' . ($endTime[1][1] - $startTime[1][1]); 
} 
function date2epoch($date, $format='m/d/Y') 
{ 
    $date = split('/', $date); 
    return mktime('0', '0', '0', $date[0], $date[1], $date[2]); 
} 
?> 
+0

我編輯了我的問題來澄清問題。你能否重新表達你的答案? – 2008-10-05 21:50:03

+0

經過測試和工作。 – UnkwnTech 2008-10-06 02:06:38

2

如果你有一個可用的日期,你應該使用日期+時間的組合,這不會是一個問題。

如果你知道的時間跨度會少於24小時:

if endtime < starttime then endtime = endtime + 24 hours 
2

在大多數語言,日期/日期/等等。類有這樣的事情的方法。使用這些時,在執行算術之前將所有日期轉換爲UTC是最佳做法。

例如,C#:

// In UTC, preferably 
DateTime ClockIn; 
DateTime ClockOut; 

ClockIn = ...; 
ClockOut = ...; 

TimeSpan TimeWorked = ClockOut.Subtract(ClockIn); 
float HoursWorked = TimeWorked.TotalHours(); 
1

如果這兩個時間不在同一時區,則需要在進行計算之前將它們轉換爲UTC :)在這裏可能不適用,但這是一個常見問題。