2008-10-05 4 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 Epoch, таким образом, что это так просто, как

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

В большинстве языков Дата/DateTime/и т.д.. классы имеют методы для подобных вещей. При их использовании лучше всего конвертировать все даты в UTC перед выполнением арифметики.

например, C#

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

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

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

и если оба раза не находятся в одном и том же часовом поясе, вам нужно будет преобразовать их в UTC, прежде чем делать расчеты. Может быть, здесь не применимо, но это распространенная проблема.

Смежные вопросы