Algorithm 计算午夜的时差

Algorithm 计算午夜的时差,algorithm,time,Algorithm,Time,这是一件我永远无法去工作的事情。 我的问题是检测一天的结束和下一天的开始,然后将差异分为每一天 假设你想计算一个工资率,但它必须跨越午夜 它还适用于计算在定时系统上运行的时间,或者计算它应该运行的时间差。我更喜欢在Unix Epoch中记录所有时间,这样就可以 hoursWorked = ((stopTime - startTime)/60)/60 这是一个完整的解决方案,它是用PHP编写的,但应该很容易用任何语言构建: <?php $startTime = "12/31/2008 22

这是一件我永远无法去工作的事情。
我的问题是检测一天的结束和下一天的开始,然后将差异分为每一天

假设你想计算一个工资率,但它必须跨越午夜


它还适用于计算在定时系统上运行的时间,或者计算它应该运行的时间差。

我更喜欢在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]);
 }
?>

如果您有一个可用的日期,您应该使用日期+时间的组合,这不会是一个问题

如果您知道时间跨度将小于24小时:

if endtime < starttime then endtime = endtime + 24 hours
如果endtime
在大多数语言中,Date/DateTime/等类都有类似的方法。使用这些参数时,最佳做法是在执行算术之前将所有日期转换为UTC

e、 g,C#:


在系统中,这显然是一个很小的问题,因为开始时间和结束时间都是包含日期和时间的数据结构。但是有很多系统不这样做。计时系统通常有一条包含日期、开始时间和结束时间的记录。在这种情况下,问题就不那么琐碎了

我想,你问了两个问题:

  • 我如何判断时间跨度是否跨越午夜
  • 如果时间跨度跨越午夜,有多少时间发生在第一天,有多少时间发生在第二天
  • 第一个问题很容易回答:如果结束时间早于开始时间,那么时间跨度已经过了午夜


    如果是这种情况,那么您需要计算两个金额。日期上发生的时间跨度量是从开始时间到午夜之间的时间。下一个日期发生的时间跨度为午夜和结束时间之间的时间(即仅为结束时间).

    如果两个时间不在同一时区,则在进行计算之前,您需要将它们转换为UTC:)可能不适用于此处,但这是一个常见问题。

    我编辑了我的问题以澄清此问题。你能重新表述你的答案吗?顺便说一句:PHP只有在由糟糕的程序员构建时才是糟糕的。在计算工资率时,通常只考虑工作时间,想想一个酒店职员从晚上10点开始工作到早上6点,他仍然工作8小时,尽管他的工作时间实际上是两天,但是如果一天与另一天的比率不同,你应该用另一个乘数来计算其中的一些小时。谢谢你澄清我自己的问题,但这正是我想要的!!即使你没有约会,这仍然可以。午夜后的时间可以被视为“加上24小时”。从晚上11:30(23:30)到早上5:30(5:30+24:00=29:30)很容易计算。
    // In UTC, preferably
    DateTime ClockIn;
    DateTime ClockOut;
    
    ClockIn = ...;
    ClockOut = ...;
    
    TimeSpan TimeWorked = ClockOut.Subtract(ClockIn);
    float HoursWorked = TimeWorked.TotalHours();