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
-
Datenbank 073_Arbeitszeiten im Webinarteam,
kann man alles herausfinden :-)
-
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.
-
Einfach ein Enail an support@ninoxdb.de schreiben und sich für das Webinarteam freischalten lassen
-
Ich werde mal knobeln
-
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
-
Danke, BugTrapper.
Ich habe nochmals angefragt.
-
Hi Leo.
Vielen Dank für deine Hilfe.
Was würden wir ohne dich nur machen.
LG
Peer
-
time() hat ich schon in mein Projekt, hatte aber damit eine Endlosschleife produziert und konnte meine Datenbank nicht mehr öffnen.
-
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 -
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
-
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
-
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 :-)
-
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.
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.
-
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 :-)
-
an Copytexter:
Umrechnung von Stunden dezimal in hh:mm, wie hast Du das gemacht ?
bevor ich lange suchen muss
-
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)
-
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.
-
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) -
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
-
Hast du getestet, ob die Ergebnisse stimmen?
-
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.
-
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.
-
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:
-
Ich habe “Datum+Zeit”-Felder genommen, nicht nur “Zeit”-Felder.
-
Mache morgen mal ne Hardcopy, wenn ich wieder am PC sitze. Habe noch Urlaub :-)
Content aside
- vor 5 JahrenZuletzt aktiv
- 31Antworten
- 5576Ansichten