这是我永远无法工作的一件事 我的问题是检测一天的结束和下一天的开始,然后将差异分成每一天。
想象一下,您想要计算工资率,但必须跨越午夜。
它也适用于计算在定时系统上运行的时间,或者它应该运行的时差。
答案 0 :(得分: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]);
}
?>
答案 1 :(得分:7)
在开始和结束时间是包含日期和时间的数据结构的系统中,这显然是一个微不足道的问题。但是有很多系统没有这样做。计时系统常常有一条包含日期,开始时间和结束时间的记录。在这种情况下,问题就不那么重要了。
我认为,你有两个问题要求:
第一个问题很容易回答:如果结束时间在开始时间之前,则时间跨度已经过了午夜。
如果是这种情况,那么您需要计算两笔金额。日期发生的时间跨度是从开始时间到午夜之间的时间。下一个日期发生的时间跨度是午夜和结束时间之间的时间(即结束时间)。
答案 2 :(得分:2)
如果您有可用日期,则应该使用日期+时间的组合,这不会有问题。
如果你知道时间跨度不到24小时:
if endtime < starttime then endtime = endtime + 24 hours
答案 3 :(得分:2)
在大多数语言中,日期/日期时间/等。类有这样的方法。使用这些时,最佳做法是在执行算术之前将所有日期转换为UTC。
例如,C#:
// In UTC, preferably
DateTime ClockIn;
DateTime ClockOut;
ClockIn = ...;
ClockOut = ...;
TimeSpan TimeWorked = ClockOut.Subtract(ClockIn);
float HoursWorked = TimeWorked.TotalHours();
答案 4 :(得分:1)
如果两个时间都不在同一时区,你需要在进行计算之前将它们转换为UTC :)可能不适用于此,但这是一个常见的问题。