2016-03-26 37 views
0

我有一個用PHP編寫的界面,用於記錄員工工作時間。爲了計算換檔差異,我想添加一個新算法來測量在特定小時之間工作的時間量。我使用MySQL的unix_time()作爲時間戳。計算兩次之間的部分時間

示例:員工從下午6點工作到凌晨2點。在晚上10點到上午6點之間有一個有償轉換差。員工收到4小時的正常工資,4小時的工資+差額。

$start_time = 1459015200; // 18:00 03/26/2016 
$end_time = 1459044000; // 02:00 03/27/2016 

$diff_start = mktime('22','00','00','3','26','2016'); 
$diff_end = mktime('06','00','00','3','27','2016'); 

我想寫給大集的時間可能工作,一個腳本,計算時間晚上10點至下午6點之間工作的量。這個答案完成似乎做我在找什麼,除了在MySQL:Calculating time difference before 6am and after 10pm in MySQL

這個答案是類似於我的問題:Calculate the number of hours in a given timeframe between two datetimes,但依賴於一個循環。鑑於時間以秒爲單位輸入,基於unix_time,我假設使用一個循環將需要一秒增量(這意味着每週有數千條記錄通過循環進行很多次循環)。

有沒有一種有效的方法(如MySQL示例)在PHP中執行此操作,而不需要像第二個答案中建議的那樣循環每增加一秒/每分鐘/小時?

+0

22-18 + 6-2?差速器開始減檔開始,再加上差速器結束減去換檔結束?也許我沒有跟着。 – bishop

+1

dst切換期間轉換!決定命運的時間。 – Jack

+0

你不是在開玩笑。也許有一天我會花時間轉換成不同的格式。 – thebarless

回答

1

有:使用陣列與特殊形式的鍵。首先

mktime('22','00','00','3','26','2016') => 1459026000 
mktime('06','00','00','3','27','2016') => 1459051200 

現在建立你差陣列:

$shifts=array (
    0 => 0, 
    1459026000 => $diff, 
    1459051200 => 0 
); 

這意味着,從時間戳0..1459025999的差是0,從1459026000到1459051199的差是$diff和1459051200至無限再次爲0。當然,你真正的換班表會更大。

現在通過這個數組soemthing像foreach ($shifts as $start=>$differential)剛好運行一次,並比較$start$start_time$end_time,這些情況:

  • $start>$end_time:忽略,這是在未來
  • $start<$start_time:忽略,這是過去的
  • else:計算秒數並使用$差分
+0

當你有一個迭代$ diff = 1和$ start <$ start_time時,你不知道是否$ nextStart> $ start_time – Jack

+0

@Jack - 1,所以這是行不通的。$ diff的值是對於時間計算來說不重要 - 它可以是-3.1415而不改變算法; 2.雖然我對**下一個**開始一無所知,但我知道關於**前一個**開始的所有內容,這是數組第一行('0 => 0')的基本原理。 ,所以我在接下來處理這個案例,而不是在'else'分支的前一個迭代中。 –

+0

我沒有得到算法。假設您有$ start_time = 1459029600(11:00 PM)和$ end_time = 1459036800(01:00 AM)。根據您陳述的情況,您的所有迭代都應該被忽略。 – Jack

0

喜歡這個問題。看起來像面試問題。我花了一些時間來實現這個效率,沒有循環。首先我執行以下操作:

function date_intersection($a_from, $a_to, $b_from, $b_to); 

返回兩個時間範圍之間的秒數。

然後,與該移位長度不能超過24小時的限制,我需要構建兩個範圍塊:

  • 這是您的當前時移
  • 的之前與差動範圍範圍具有差分這是後

它之後,溶液是直接的:

$total = $end_time - $start_time; 
$differ = date_intersection($b1s, $b1e, $start_time, $end_time) + date_intersection($b2s, $b2e, $start_time, $end_time); 
$normal = $total-$differ; 

有效解決此問題涉及不使用mktime()或date()來提取部分日期,因爲您真的可以通過unix-timestamp解決模塊運算符的問題。但是照顧DST真的讓它變得複雜。 如果你今晚只問過這個問題,我會回答之前(不正確):)

+0

我欣賞後續文章。我不確定我是否理解你的'date_intersection'函數的重點。有東西被切掉了嗎?另外,$ b1s/e&$ b2s/e的目的是什麼? – thebarless

+0

我認爲沒有什麼時間差異開始/結束,什麼時間工作班次開始/結束的限制。如果你有後者,問題是微不足道的,因爲你可以預先計算所有可能的變化的差異。(date_intersection(10,15,12,22)== 3)和(b1s = block_1_start)。 – Jack