2 Stimmen

Berechnung der Zeitdifferenz über Mitternacht

Das ist die eine Sache, die ich nie zum Laufen bringen konnte.
Mein Problem besteht darin, das Ende eines Tages und den Beginn des nächsten Tages zu erkennen und dann die Differenz in jeden Tag aufzuteilen.

Stellen Sie sich vor, Sie wollen einen Lohnsatz berechnen, der sich aber über Mitternacht erstrecken muss.

Dies gilt auch für die Berechnung der Zeit, die für die Ausführung eines zeitgesteuerten Systems benötigt wird, oder für die Zeitdifferenz, die für die Ausführung benötigt wird.

8voto

UnkwnTech Punkte 83318

Ich ziehe es vor, alle Zeiten in Unix Epoch zu erfassen, so ist es einfach, die

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

Hier ist eine vollständige Lösung in PHP, aber es sollte einfach genug sein, um sie in jeder Sprache zu erstellen:

<?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]);
 }
?>

7voto

Robert Rossney Punkte 91100

Dies ist offensichtlich ein triviales Problem in Systemen, in denen die Anfangs- und Endzeiten Datenstrukturen sind, die sowohl Datum als auch Uhrzeit enthalten. Aber es gibt viele Systeme, die dies nicht tun. Es ist sehr üblich, dass Zeiterfassungssysteme einen einzigen Datensatz haben, der ein Datum, eine Startzeit und eine Endzeit enthält. In diesem Fall ist das Problem weniger trivial.

Ich glaube, es gibt zwei Fragen, die Sie stellen:

  1. Wie kann ich feststellen, ob eine Zeitspanne über Mitternacht hinausgeht?
  2. Wenn eine Zeitspanne über Mitternacht hinausgeht, wie viel von der Zeit ist am ersten Tag und wie viel am zweiten Tag passiert?

Die erste Frage ist leicht zu beantworten: Wenn die Endzeit vor der Startzeit liegt, hat die Zeitspanne Mitternacht überschritten.

Wenn dies der Fall ist, müssen Sie zwei Beträge berechnen. Der Betrag der Zeitspanne, die an dem Datum aufgetreten ist, ist die Zeit zwischen der Startzeit und Mitternacht. Der Betrag der Zeitspanne, die am nächsten Datum aufgetreten ist, ist die Zeit zwischen Mitternacht und der Endzeit (d. h. nur die Endzeit).

3voto

Mark Ransom Punkte 283960

Wenn Sie ein Datum zur Verfügung haben, sollten Sie mit der Kombination aus Datum und Uhrzeit arbeiten, und es wird kein Problem sein.

Wenn Sie wissen, dass die Zeitspanne weniger als 24 Stunden betragen wird:

if endtime < starttime then endtime = endtime + 24 hours

2voto

Michael Haren Punkte 101002

In den meisten Sprachen haben die Klassen Date/DateTime/etc. Methoden für solche Dinge. Wenn Sie diese verwenden, ist es am besten, alle Datumsangaben in UTC zu konvertieren, bevor Sie arithmetische Berechnungen durchführen.

z.B. C#:

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

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

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

1voto

ShayH Punkte 11

Und wenn beide Zeiten nicht in der gleichen Zeitzone liegen, müssen Sie sie vor der Berechnung in UTC umrechnen :) Das mag hier nicht zutreffen, aber es ist ein häufiges Problem.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X