0

Verbleibende Zeit bis Mitternacht berechnen

Hallo.

Ich möchte aus Beginn (Zeit (Arbeitsbeginn)) und Ende (Zeit (Arbeitsende)) einer Arbeitszeit die Nachtzeit errechnen. Die Nachtzeit beginnt 20 Uhr und endet 6:00. Meine Überlegung ist, das man vorher erstmal abfragt, ob die Zeit nach 20 Uhr oder/und 6 Uhr liegt.

let intNachtBeginn := 'Zeit (Arbeitsbeginn)' > 6 or < 20;

let intNachtEnde := 'Zeit (Arbeitsende)' > 6 or < 20;

Jetzt sollte die Zeit bis 24 Uhr hoch/zurückgerechnet werden und in jeweils einer Variable gespeichert werden und zusammengezählt werden.

Hier scheitert mein mageres Wissen an der Umsetzung.

Wie stelle ich das an, dass bei zB 21:05 Beginn noch 3:55 bis 0:00 und bei Ende 4:35, 4:35 ab 0:00 zusammen 8:30 ergeben?

LG

Peer

31 Antworten

null
    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Datenbank 073_Arbeitszeiten im Webinarteam,

    kann man alles herausfinden :-)

    • Peer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ich bin zwar für das Webinar registriert und schaue fleißig Mittwochs zu, bin aber noch nicht dahinter gestiegen, wie ich an die Beispiele komme,  die öfters hier im Forum erwähnt werden.

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Einfach ein Enail an support@ninoxdb.de schreiben und sich für das Webinarteam freischalten lassen 

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ich werde mal knobeln

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hier meine Bastellösung für ein Funktionsfeld. Das Gegenteil von elegant (nicht nachmachen, Kinder!), geht sicher deutlich besser, aber es funktioniert immerhin und berücksichtigt auch Angaben wie 18:00 bis 23:00 oder 1:00 bis 7:00 Uhr: 

     

    let Nach20 := time(0, 0);
    let Vor6 := time(0, 0);
    if Startzeit > Endzeit then
        Nach20 := if Startzeit >= time(20, 0) then
                time(24, 0) - Startzeit
            else
                time(24, 0) - Startzeit - (time(20, 0) - Startzeit)
            end;
        Vor6 := if Endzeit <= time(6, 0) then
                Endzeit
            else
                Endzeit - (Endzeit - time(6, 0))
            end
    else
        if Endzeit >= time(20, 0) then
            Nach20 := if Startzeit <= time(20, 0) then
                    Endzeit - time(20, 0)
                else
                    Endzeit - Startzeit
                end
        else
            if Startzeit <= time(6, 0) then
                if Endzeit > time(6, 0) then
                    Vor6 := time(6, 0) - Startzeit
                else
                    Vor6 := Endzeit - Startzeit
                end
            end
        end
    end;
    Nach20 + Vor6

    • Peer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Danke, BugTrapper.

    Ich habe nochmals angefragt.

    • Peer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hi Leo.

    Vielen Dank für deine Hilfe.

    Was würden wir ohne dich nur machen.

    LG

    Peer

    • Peer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    time() hat ich schon in mein Projekt, hatte aber damit eine Endlosschleife produziert und konnte meine Datenbank nicht mehr öffnen.

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hier meine Lösung, noch verbesserungsbedürftig. In einem Berechnungsfeld wird die Anzahl der Nachtstunden ausgegeben (hat etwas gedauert, weil es sehr mühsam war, das alles AUF DEM HANDY zu tippen :-) :

     

    let AnzahlNachtstunden := 0;
    if Arbeitende - Arbeitstart > 0 then
    if day(Arbeitstart) = day(Arbeitende) then
    AnzahlNachtstunden := (Arbeitende - Arbeitstart) / (3600 * 1000)
    else
    let bisMitternacht := appointment(Arbeitstart, date(year(Arbeitstart), month(Arbeitstart), day(Arbeitstart) + 1) + time(0, 0, 0));
    if duration(bisMitternacht) >= 4 then
    AnzahlNachtstunden := number(duration(bisMitternacht) / (3600 * 1000))
    end;
    let abMitternacht := appointment(date(year(Arbeitstart), month(Arbeitstart), day(Arbeitstart) + 1) + time(0, 0, 0), Arbeitende);
    if duration(abMitternacht) > 0 then
    AnzahlNachtstunden := AnzahlNachtstunden + min(6, number(duration(abMitternacht) / (3600 * 1000)))
    end
    end
    end;
    AnzahlNachtstunden

    • Peer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Danke, Bug.

    Ist ne Menge Text zum durchstöbern. Da werde ich mich diese Woche mal intensiver mit der Referenz beschäftigen müssen.

    LG

    Peer

    • Leonid_Semik
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hallo zusammen,

    erstens möchte ich die Danksagungen an Copytexter weiterreichen, hier habe ich noch nichts geschrieben. Zweitens möchte ich auch eine Lösung vorschlagen. Ninox kann die Dauer zwischen zwei Zeitstempel (datetime) korrekt berechnen. Wenn wir die Zeiten in Zeitstempel umwandeln würden, wäre das Problem gelöst. Das richtige Datum in ein Zeitstempel zu setzen kann man so lösen: wenn Anfangszeit > Endzeit dann bei Anfang das Datum von Datum und bei Ende -Datum +1. Da die Arbeitsstunden später sicherlich mit Stundenlohn verrechnet werden, muss man das Ergebnis in eine Zahl umwandeln. Die Zeitdauer wird als Zahl in Millisekunden angezeigt, diese muss man dann durch 1000, dann durch 60 und nochmal durch 60 dividieren um auf die Stunden zu kommen:

    —-

    if Arbeitsbeginn and Arbeitsende then
    let myTime := if Arbeitsbeginn > Arbeitsende then
    datetime(Datum + 1, Arbeitsende) - datetime(Datum, Arbeitsbeginn)
    else
    Arbeitsende - Arbeitsbeginn
    end;
    number(myTime / 3600000)
    end

    —-

    Leo

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    an Leo:

    glaube, dass das nicht geht, weil Peer ja nur die Stunden der Nachtzeit zwischen 20:00 Uhr und 6:00 Uhr haben will.

     

    Aber egal, sind ja nur Ansätze und programmieren können wir alle, was wir unter Beweis gestellt haben :-)

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Moin, ich glaube wie Leo auch, dass es da noch einen effizienteren Ansatz als meinen geben müsste. Aber immerhin funktioniert er ja. Ich habe zur Überprüfung noch mal verschiedene Kombinationen erfasst, und die Zeit zwischen 20 und 6 Uhr wird immer korrekt berechnet, wenn ich es richtig sehe.

     

    Ninox_Zeit20-06Uhr

     

    Allerdings habe ich nicht das Datum berücksichtigt, sondern bin davon ausgegangen, dass es sich immer um eine zusammenhängende Arbeitszeit handelt, die sich nie über mehrere Tage hinwegzieht.

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Mit "Nur" Zeitfeldern wird es übersichtlicher, ich habe 2 kombinierte "Datum + Zeit"-Felder genommen. Da gibts dann natürlich jede Menge Fallunterscheidungen.

    Egal wie, hauptsache es funktioniert :-)

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    an Copytexter:

    Umrechnung von Stunden dezimal in hh:mm, wie hast Du das gemacht ?

    bevor ich lange suchen muss

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ich hab's umgekehrt gemacht, also die berechnete Zeit in einen Dezimalwert umgewandelt.

    Umrechnung Zeitangabe (4:15) in Dezimalwert (4,25):
    number(ZEITWERT / 3600000)

    Umrechnung Dezimalwert (8,5) in Zeitangabe (8:30):
    time(DEZIMALWERT * 3600000)

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Nebenbei (@BugTrapper): Dein Code hat bei mir nicht so recht funktioniert. Brachte bei den meisten Kombinationen falsche Ergebnisse. Ich habe aber nicht versucht, ihn zu entschlüsseln, kann also nicht sagen, wo genau der Fehler liegt. 

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hier ist noch ne Lösung, mit Zeitstempeln a la Leo, die kannte ich vorher noch gar nicht, aber jetzt:

     

    let s := number(datetime(Start));
    let e := number(datetime(Ende));
    let acht := datetime(year(Start), month(Start), day(Start), 20, 0, 0);
    let sechs := datetime(year(Start), month(Start), day(Start) + 1, 6, 0, 0);
    let Nachtstunden := 0;
    if day(Start) + 1 = day(Ende) then
    for i from s to e step 1000 do
    if i >= number(acht) and i <= number(sechs) then
    Nachtstunden := Nachtstunden + 1000
    end
    end
    end;
    if day(Start) = day(Ende) then
    let mitternacht := datetime(year(Start), month(Start), day(Start), 0, 0, 0);
    for i from s to e step 1000 do
    if i >= number(acht) and i <= number(mitternacht) then
    Nachtstunden := Nachtstunden + 1000
    end;
    if i >= number(mitternacht) and i <= number(sechs) then
    Nachtstunden := Nachtstunden + 1000
    end
    end
    end;
    time(Nachtstunden)

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Verwendet habe ich:

    “Start” = Datum+Zeit-Feld (Arbeitszeitstart)

    “Ende”= Datum+Zeit-Feld (Arbeitszeitende)

    und ein Berechnungsfeld mit Namen “Nachtstunden”

    ”acht” ist der Zeitstempel von 20:00 Uhr

    “sechs” ist der Zeitstempel von 6:00 Uhr

    “mitternacht” ist der Zeitstempel von 0:00 Uhr

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Hast du getestet, ob die Ergebnisse stimmen?

    • Peer
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ihr nimmt mir es hoffentlich nicht übel, dass ich mich da raus halte. ;-))

    Trotzdem finde ich es sehr interessant, wie sich ein scheinbar "einfaches" Problem ausweiten kann. :-)

    Ich danke euch allen, mitlesen zu dürfen.

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Jau, getestet, aber es wird nicht funzen, wenn Arbeitsstart und Endzeit 2 Tage auseinanderliegen.

    Dann dürfte die for-Schleife etwas sehr langsam werden.

    Müsste man dann noch nen Alert bringen.

    Ninox-/ oder Unix-Zeitstempel gehen von 1970 - 2038, und was ist danach ?

    Lustig ist, dass die for-Schleife so schnell läuft.

    Das Problem ist nicht trivial, ähnlich eines Zeigers im Polardiagramm, der von 345 Grad über 360, also wieder bei Null Grad anfängt, sogenannter Phasensprung.

    • Ninox-Professional
    • planoxpro
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Arbeitszeit über mehrere Tage muss man hier wohl nicht berücksichtigen. Das dürfte in der Praxis kaum vorkommen (wäre nach dem Arbeitszeitgesetz auch gar nicht erlaubt), und für länger dauernde Bereitschaftszeiten o. ä. bräuchte man neben den Uhrzeiten ja auch noch Tagesdaten. Deshalb würde ich solche Sonderfälle erst mal außen vor lassen.

     

    Aber wie hast du deinen Code getestet? Bei mir bringt er nämlich auch wieder falsche Ergebnisse:

     

    Ninox_Zeit20-06Uhr_Variante1

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Ich habe “Datum+Zeit”-Felder genommen, nicht nur “Zeit”-Felder.

    • BugTrapper
    • vor 5 Jahren
    • Gemeldet - anzeigen

    Mache morgen mal ne Hardcopy, wenn ich wieder am PC sitze. Habe noch Urlaub :-)

Content aside

  • vor 5 JahrenZuletzt aktiv
  • 31Antworten
  • 5576Ansichten