Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Industrieminuten (https://www.delphipraxis.net/183603-industrieminuten.html)

StepByStep 22. Jan 2015 08:00

Delphi-Version: XE2

Industrieminuten
 
Guten Morgen zusammen,

bevor die Frage aufkommen sollte: Ja, ich habe die SuFu genutzt.

Mein Problem ist folgendes:
Ich möchte zwei TDateTimes vergleichen und mir die Differenz in Stunden ausgeben lassen.
Mir sind die Funktionen YearBetween, HoursBetween, etc. bekannt und leider auch zu ungenau.
Deshalb habe ich eine eigene Funktion geschrieben:

Delphi-Quellcode:
function TXmlfunction.GetDate(dtVon, dtBis: TDateTime): string;
var
  dtDate: TDateTime;
  sHour: string;
  sTime: string;
begin
  dtDate := (dtBis - dtVon);
  sHour := TimeToStr(dtDate);
  sTime := FloatToStr(StrToFloat(sHour[1] + sHour[2]) + StrToFloat(sHour[4] + sHour[5]) / 60);
  result := sTime;
end;
Das Problem was sich nun stellt ist, dass wenn ich beispielsweise folgende Rechnung habe:

22.01.2015 10:00:00 - 21.01.2015 10:00:00,

dann ist das Ergebnis 0, da er durch den Befehl
Delphi-Quellcode:
TimeToStr()
nur die Stunden nimmt.
Ich kann aber nicht
Delphi-Quellcode:
DateTimeToStr()
nutzen, weil ich so nur Müll rausbekomme.

Frage: Wie stelle ich das jetzt am geschicktesten an?

Gruß
Jan

DeddyH 22. Jan 2015 08:05

AW: Industrieminuten
 
Wozu dieses ganze String-Geraffel, wäre z.B. DecodeDateTime nicht zielführender?

himitsu 22. Jan 2015 08:10

AW: Industrieminuten
 
Oder Delphi-Referenz durchsuchenHourOf, Delphi-Referenz durchsuchenMinuteOf, Delphi-Referenz durchsuchenMinutesBetween usw.


Abgesehn von den fehleranfälligen Stringbehandlungen ... StrToFloat, obwohl man nur ganze Zahlen rein gibt.


Zitat:

Das Problem was sich nun stellt ist, dass wenn ich beispielsweise folgende Rechnung habe:
Du rechnest nur mit dem Stundenanteil, da muß es bei Tagesüberschreitungen natürlich knallen.
Wie wäre es, wenn du auch die Tages/Monats/Jahres-Anteile mit einrechnest? :roll:

Und was ist mit den MinutenSekunden-Anteilen?
22.01.2015 10:00:00 - 22.01.2015 09:30:00

Nur das Markierte wird von dir beachtet und der Rest einfach ignoriert, da kann das doch nicht richtig funktionieren.

DeddyH 22. Jan 2015 08:44

AW: Industrieminuten
 
Nach kurzer Überlegung: die Differenz zweier TDateTime ist doch in Tagen, um also auf die Stunden zu kommen, müsste man sie doch lediglich mit 24 multiplizieren, oder mache ich da einen Denkfehler?

Sir Rufo 22. Jan 2015 08:52

AW: Industrieminuten
 
Zitat:

Zitat von DeddyH (Beitrag 1287382)
Nach kurzer Überlegung: die Differenz zweier TDateTime ist doch in Tagen, um also auf die Stunden zu kommen, müsste man sie doch lediglich mit 24 multiplizieren, oder mache ich da einen Denkfehler?

Ja und Nein - kein Denkfehler :thumb:

UPDATE Aber bitte keine MagicValues im Code benutzen sondern Delphi-Referenz durchsuchenSystem.SysUtils.HoursPerDay ;)

UPDATE 2 Die einzige Zahl, die keine MagicValue ist, ist die 42 :mrgreen:

Sherlock 22. Jan 2015 08:53

AW: Industrieminuten
 
Zitat:

Zitat von DeddyH (Beitrag 1287382)
Nach kurzer Überlegung: die Differenz zweier TDateTime ist doch in Tagen, um also auf die Stunden zu kommen, müsste man sie doch lediglich mit 24 multiplizieren, oder mache ich da einen Denkfehler?



Sherlock

StepByStep 22. Jan 2015 09:22

AW: Industrieminuten
 
Danke schonmal für die Antworten. Mein Programm erfasst Arbeitszeiten.

Zitat:

Und was ist mit den Minuten-Anteilen?
22.01.2015 10:00:00 - 22.01.2015 09:30:00
Mit der Funktion die ich dort geschrieben habe, werden in der Tat auch die Minuten mitgerechnet @himitsu

Zitat:

UPDATE Aber bitte keine MagicValues im Code benutzen sondern
Was genau ist eine MagicValue? Noch nie gehört.

Zitat:

Nach kurzer Überlegung: die Differenz zweier TDateTime ist doch in Tagen, um also auf die Stunden zu kommen, müsste man sie doch lediglich mit 24 multiplizieren, oder mache ich da einen Denkfehler?
Denkfehler nicht nein, aber bei mir glaube ich schon. Würde dieser Denkansatz dann aus meinem Code folgendes machen:

Delphi-Quellcode:
function TXmlfunction.GetDate(dtVon, dtBis: TDateTime): string;
var
  dtDate: TDateTime;
begin
  dtDate := ((dtBis - dtVon)*24);
  result := DateTimeToStr(dtDate);
end;
Gruß
Jan

himitsu 22. Jan 2015 09:26

AW: Industrieminuten
 
Zitat:

Zitat von StepByStep (Beitrag 1287389)
Mit der Funktion die ich dort geschrieben habe, werden in der Tat auch die Minuten mitgerechnet @himitsu

Ohhhh, da hat mir die gut benannte Variable "sHour" einen Streich gespielt. :oops:
(hab da schnell und heimlich da oben meine Antwort angepasst)

Zitat:

MagicValue
Eine einfach so im Code stehende Zahl, deren Bedeutung man nicht sofort erkennt.
Darum gibt es auch diese "sprechenden" Konstanten. (Oder man schreibt ständig "unnötige" Kommentare in seinen Code :stupid:)

DateTimeToStr wird nur zum "Konvertieren" von DateTime-Werten benutzt (Tage = ganzzahliger Anteil und Nachkommateil ist Stunden/Minuten/Sekunden ... bzw. "Tage" seit Anfang)
Mal "24" (die Fernsehserie) ist das natürlich kein DateTime-Wert mehr, sondern ein Stunden-Wert. (FloatToStr, Format, gerundet und dann IntToStr usw.)

DeddyH 22. Jan 2015 09:29

AW: Industrieminuten
 
So ungefähr, aber die 24 ist nun der angesprochene Magic Value: da steht eine 24 und niemand weiß, was sie zu bedeuten hat. Aus diesem Grund benutzt man Konstanten mit sprechenden Bezeichnern.
Delphi-Quellcode:
dtDate := ((dtBis - dtVon)*DateUtils.HoursPerDay);
So wird einem auch nach Jahren sofort klar, dass das mit Stunden je Tag zu tun hat.

StepByStep 22. Jan 2015 09:43

AW: Industrieminuten
 
Zitat:

Mal "24" (die Fernsehserie) ist das natürlich kein DateTime-Wert mehr, sondern ein Stunden-Wert.
@himitsu Was ist das für eine Fernsehsendung? Ich bin Baujahr '95 :wink: Und die Ausgabe soll auch in Stunden erfasst werden, nicht in Minuten. Wobei, naja quasi Stunden, ich hätte gerne Industrieminuten, also eine Stunde = 1, eine halbe Stunde = 0,5

Check, ich probier es gleich mal aus. :)

Gruß
Jan

Edit: DateUtils.HoursPerDay sind bei mir zwei undeklarierte Bezeichner. Ich habe in den Uses System.DateUtils eingebunden. Bin ich dumm oder sehe ich den Fehler nicht?

Perlsau 22. Jan 2015 09:51

AW: Industrieminuten
 
Zitat:

Zitat von StepByStep (Beitrag 1287379)
Mir sind die Funktionen YearBetween, HoursBetween, etc. bekannt und leider auch zu ungenau.

Dann versuch's doch mal mit MilliSecondsBetween :-D
Oder wie genau möchtest du es denn genau haben :?:

mkinzler 22. Jan 2015 09:59

AW: Industrieminuten
 
Er möchte eigentlich den Minutenanteil in Stunden in der Industriezeit

DeddyH 22. Jan 2015 10:14

AW: Industrieminuten
 
Zitat:

Zitat von StepByStep (Beitrag 1287398)
DateUtils.HoursPerDay sind bei mir zwei undeklarierte Bezeichner. Ich habe in den Uses System.DateUtils eingebunden. Bin ich dumm oder sehe ich den Fehler nicht?

Mein Fehler, die Konstante ist in SysUtils deklariert, hat Sir Rufo oben auch richtig geschrieben.

himitsu 22. Jan 2015 10:29

AW: Industrieminuten
 
HoursBetween zu ungenau?

Delphi-Referenz durchsuchenHourSpan (man achte auf den Result-Typ)
oder
Delphi-Referenz durchsuchenMinutesBetween / MinsPerHour

Bei Google suchen24 (OK, ist von 2001, aber letztes Jahr lief das, glaub ich, mal wieder im deutschen Free-TV)

Zitat:

Mein Fehler, die Konstante ist in SysUtils deklariert
F1 (nicht die Formel-1)

Uwe Raabe 22. Jan 2015 10:43

AW: Industrieminuten
 
Zitat:

Zitat von mkinzler (Beitrag 1287406)
Er möchte eigentlich den Minutenanteil in Stunden in der Industriezeit

Da eine Industriestunde einer normalen Stunde entspricht, ist das doch vollkommen irrelevant. Eine halbe Stunde wird dabei doch als 0.5 dargestellt. Das sind zwar 50 Industrieminuten, aber die Einheit soll ja wohl Stunden sein.

Sehe ich das jetzt zu einfach oder kann man das nicht durch dieses Konstrukt erreichen:

Delphi-Quellcode:
uses
  System.SysUtils,
  System.Math;
...
function IndustrieStundenZwischen(DT1, DT2: TDateTime): Double;
{ Liefert die Differenz in Stunden mit zwei Nachkommastellen zurück und ist somit auf 1 Industrieminute genau }
begin
  result := SimpleRoundTo((DT2 - DT1)*HoursPerDay, -2);
end;

StepByStep 22. Jan 2015 10:49

AW: Industrieminuten
 
Zitat:

Da eine Industriestunde einer normalen Stunde entspricht, ist das doch vollkommen irrelevant. Eine halbe Stunde wird dabei doch als 0.5 dargestellt. Das sind zwar 50 Industrieminuten, aber die Einheit soll ja wohl Stunden sein.
Ich möchte so rechnen:

60 ~ 1
30 ~ 0.5
etc.

So können doch 0.5 nicht 50 Industriemethoden entsprechen, oder?
Man man man ich weiß schon, warum ich Uhren damals schon nicht mochte.

Gruß
Jan

Edit:
Delphi-Quellcode:
((dtBis - dtVon) * System.SysUtils.HoursPerDay);
liefert mir was falsches...

Noch n Edit: Habe eben mal das von himitsu ausprobiert, aber ich will nicht 0,99999... ausgegeben bekommen, sondern eins. Wie runde ich denn?

mkinzler 22. Jan 2015 10:58

AW: Industrieminuten
 
Das sind dann Minuten / MinutenProStunde

30/60 = 0,5

Uwe Raabe 22. Jan 2015 11:35

AW: Industrieminuten
 
Zitat:

Zitat von StepByStep (Beitrag 1287423)
Ich möchte so rechnen:

60 ~ 1
30 ~ 0.5
etc.

So können doch 0.5 nicht 50 Industriemethoden entsprechen, oder?

Mit "methoden" hat das jetzt zwar nichts zu tun, aber
  • 1.0 Stunde = 60 Minuten = 100 Industrieminuten (1.00)
  • 0.5 Stunden = 30 Minuten = 50 Industrieminuten (0.50)

So richtig schick wird es aber erst, wenn du mit Industriesekunden (1 Industrieminute = 100 Industriesekunden) arbeitest.

hstreicher 22. Jan 2015 11:50

AW: Industrieminuten
 
ich habe hier noch ein paar Stopuhren rumliegen die in 100/ Minuten geteilt sind ,
machte das aufaddieren von Arbeitszeiten beim erstellen von Arbeitsplänen
doch sehr viel einfacher

und gibt's auch noch zu kaufen

http://www.hanhart-stoppuhr.de/Digit...ignet::72.html

StepByStep 22. Jan 2015 12:11

AW: Industrieminuten
 
Delphi-Quellcode:
result := SimpleRoundTo((DT2 - DT1)*HoursPerDay, -2);
Danke Uwe, das funktioniert jetzt wunderbar. :thumb:

Gruß
Jan

himitsu 22. Jan 2015 12:26

AW: Industrieminuten
 
Zitat:

Zitat von StepByStep (Beitrag 1287440)
Delphi-Quellcode:
result := SimpleRoundTo((DT2 - DT1)*HoursPerDay, -2);
Danke Uwe, das funktioniert jetzt wunderbar. :thumb:

Zitat:

Zitat von himitsu (Beitrag 1287417)
Delphi-Referenz durchsuchenHourSpan (man achte auf den Result-Typ)

HourSpan + RountTo oder HourSpan + RountTo+FloatToStr oder Format oder FormatFloat oder ...

Ein kleines
Delphi-Quellcode:
-
dokumentiert den Code nicht so schön wie z.B. HourSpan.


Zitat:

Zitat von hstreicher (Beitrag 1287436)
machte das aufaddieren von Arbeitszeiten beim erstellen von Arbeitsplänen

Ein schweizer Uhrenhersteller wollte mal, gegen Ende des letzten Jahrtausends, 'ne Uhr(zeit) mit 10 Stunden á 100 Minuten pro Tag einführen ... schade daß sich das nicht durchsetzte. :stupid:

Uwe Raabe 22. Jan 2015 12:32

AW: Industrieminuten
 
Zitat:

Zitat von himitsu (Beitrag 1287441)
Ein kleines
Delphi-Quellcode:
-
dokumentiert den Code nicht so schön wie z.B. HourSpan.

Wenn dieses hier
Zitat:

Zitat von System.DateUtils.HourSpan
HourSpan always returns a positive result and therefore the parameter values are interchangeable.

keine Einschränkung bedeutet oder sogar gewollt ist, dann würde ich auch HourSpan empfehlen.

BadenPower 22. Jan 2015 14:08

AW: Industrieminuten
 
Zitat:

Zitat von himitsu (Beitrag 1287441)
Ein schweizer Uhrenhersteller wollte mal, gegen Ende des letzten Jahrtausends, 'ne Uhr(zeit) mit 10 Stunden á 100 Minuten pro Tag einführen ... schade daß sich das nicht durchsetzte. :stupid:

Und die Arbeitsverträge seiner Angestellten wären dann mit 8 Stunden pro Arbeitstag unverändert weitergelaufen.

Nette Idee!

UliBru 22. Jan 2015 15:28

Welcher Magier kennt alle Konstanten?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1287386)
UPDATE Aber bitte keine MagicValues im Code benutzen sondern Delphi-Referenz durchsuchenSystem.SysUtils.HoursPerDay ;)

Wie es der Titel schon andeutet: woher weiss ich welche Konstante in irgendeiner der gefühlt tausend Delphi-Units definiert und verfügbar sind? Muss ich mir dazu alles vorher anschauen und dann auch merken? Wem ist das noch nicht passiert, dass er etwas für sich erfindet und dann feststellt, dass es das in der Bibliothek schon gibt. Oder besser, in den Bibliotheken und damit also noch mehrfach.

Ich verstehe zwar, dass es besser ist, z.B.
Delphi-Quellcode:
const
  StdProTag = 24;
zu verwenden als die Zahl 24 irgendwo in einer Funktion in einer Formel auftauchen zu lassen.
Aber muss man deshalb gleich immer die Monsterausdrücke wie System.SysUtils.HoursPerDay bemühen? Damit eindeutig ausgeschlossen wird, dass der Compiler irgendwo eine Definition
Delphi-Quellcode:
HoursPerDay = 25
findet? Dann wäre doch die Definition eigener Konstanten sinnvoller, da weiss man was man hat. Oder?

Mikkey 22. Jan 2015 15:38

AW: Welcher Magier kennt alle Konstanten?
 
Ich kenne die auch nicht, und mache das auch so

Delphi-Quellcode:
const
  StdProTag = 24;
Wenn ich dann irgendwann darauf stoße, dass es eine solche vorgefertigte Konstante in den Delphi-Tiefen gibt, mache ich daraus

Delphi-Quellcode:
const
  StdProTag = System.SysUtils.HoursPerDay;
... und gut is.

Allerdings ist das Verwenden der Tatsache, dass ein TDateTime ein double ist, genauso magisch, wie die 24. Deshalb halte ich eine solche Multiplikation für schlechten Code. Da es genügend Funktionen gibt, die fast alle denkbaren Anforderungen abdecken, brauchts so etwas nicht.

Wenn es doch so eine Anforderung geben sollte, kann man die benötigte Funktion entsprechend selbst erstellen.

himitsu 22. Jan 2015 16:01

AW: Welcher Magier kennt alle Konstanten?
 
Zitat:

Zitat von UliBru (Beitrag 1287465)
woher weiss ich welche Konstante in irgendeiner der gefühlt tausend Delphi-Units definiert und verfügbar sind? Muss ich mir dazu alles vorher anschauen und dann auch merken?

Mit der Zeit lernt man, wo man für bestimmte Aufgaben meistens etwas findet und wo es sich wie zu suchen lohnt.

Wenn man weiß, daß es um einen Datumswert geht, braucht man nur noch un 2-3 Units zu suchen.
DateUtils und dort wo früher das Zeug rumgammelte, also vorallem die SysUtils.

Zitat:

Zitat von BadenPower (Beitrag 1287452)
Und die Arbeitsverträge seiner Angestellten wären dann mit 8 Stunden pro Arbeitstag unverändert weitergelaufen.

Eine Woche mit 10 Tagen ... und schon hast du dafür 5 Tage lang Wochenende.
Und bei 4 Wochen Urlaub im Jahr.......

StepByStep 23. Jan 2015 11:19

AW: Industrieminuten
 
Also nachdem das Rechnen nun einwandfrei funktioniert, möchte ich gerne eine TObjectlist in einem StringGrid ausgeben - das funktioniert bereits!
Es geht mir nur darum, dass ich in dieser Liste ein Kommentar habe (string) und ich dieses dort einfügen möchte.

Ich habe gelesen, dass man wohl keine Zeilenumbrüche in StringGrids machen kann, ist das richtig?
Ansonsten möchte ich nämlich so vorgehen (bisschen Pseudocode):

Code:
wenn Liste[i].DerString > Liste[i].DerString[60] (also länger als 60 Zeichen) dann
iZeichen := 60;
wiederhole:
wenn Liste[i].DerString[iZeichen] ungleich '' ist dann
iZeichen -1
ansonsten
mache dort Zeilenumbruch
bis Leerzeichen kommt
schreibe String in StringGrid mit Zeilenumbruch
Soweit meine Idee...

Uwe Raabe 23. Jan 2015 11:27

AW: Industrieminuten
 
Zitat:

Zitat von StepByStep (Beitrag 1287540)
Also nachdem das Rechnen nun einwandfrei funktioniert, möchte ich gerne eine TObjectlist in einem StringGrid ausgeben

Dann empfehle ich dir, dafür einen eigenen Thread aufzumachen.

Sir Rufo 23. Jan 2015 16:33

AW: Welcher Magier kennt alle Konstanten?
 
Zitat:

Zitat von UliBru (Beitrag 1287465)
Zitat:

Zitat von Sir Rufo (Beitrag 1287386)
UPDATE Aber bitte keine MagicValues im Code benutzen sondern Delphi-Referenz durchsuchenSystem.SysUtils.HoursPerDay ;)

Wie es der Titel schon andeutet: woher weiss ich welche Konstante in irgendeiner der gefühlt tausend Delphi-Units definiert und verfügbar sind? Muss ich mir dazu alles vorher anschauen und dann auch merken? Wem ist das noch nicht passiert, dass er etwas für sich erfindet und dann feststellt, dass es das in der Bibliothek schon gibt. Oder besser, in den Bibliotheken und damit also noch mehrfach.

Ich verstehe zwar, dass es besser ist, z.B.
Delphi-Quellcode:
const
  StdProTag = 24;
zu verwenden als die Zahl 24 irgendwo in einer Funktion in einer Formel auftauchen zu lassen.
Aber muss man deshalb gleich immer die Monsterausdrücke wie System.SysUtils.HoursPerDay bemühen? Damit eindeutig ausgeschlossen wird, dass der Compiler irgendwo eine Definition
Delphi-Quellcode:
HoursPerDay = 25
findet? Dann wäre doch die Definition eigener Konstanten sinnvoller, da weiss man was man hat. Oder?

Du musst dir diese Monster-Ausdrücke nicht merken und auch nicht verwenden. Wenn du dann feststellst, dass es so einen Wert schon als Konstante gibt, dann kannst du ja auch ganz einfach übernehmen
Delphi-Quellcode:
const
  // StdProTag = 24;
  StdProTag = System.SysUtils.HourPerDay;
Ist aber im Prinzip dann auch egal, meine Bibliothek würde ich dann nicht mehr anfassen, sondern wie gezeigt entsprechend abändern.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:22 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz