Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Dienstzeitende Rechner (https://www.delphipraxis.net/50969-dienstzeitende-rechner.html)

Ajintaro 3. Aug 2005 14:45


Dienstzeitende Rechner
 
Joten Tach meine lieben!

Ich habe schon eine Menge Dienstzeit-Ende-Countdowns geshen, die meisten wurden mit Excel erstellt. Nun möchte ich für einen Kameraden einen etwas luxuriöseren Dienstzeitende Counter erstellen. Ich dachte mit dem Delphi Easy Helper und der Wühlerei hier in den Foren würde ich das schon hinbekommen.

Hier im Forum gibts eine Vielzahl von Datum/Uhrzeit Probleme und deren Lösung, aber irgendwie sehe ich den Wald vor lauter Bäumen nicht mehr. Ziel des Programms ist ganz simpel:

Man gibt:
- Diensteintritt ein (Editfeld.Text im Format 10.10.1998) und
- Dienstzeitende (ebenfalls Editfeld.Text z.B. 14.05.2014) ein

fertig.

Als Antwort sollte das Programm dann ausspucken:

Herr xy hat seit Montag, dem 10.10.1998 genau 7 Jahre, 7 Monate, 7 Tage, 7 Std, 7 Minuten und 43 Sekunden gedient und muss noch 9 Jahre, 7 Monate .... dienst leisten.

Folgendes hab ich bis jetzt mal realisiert:

Delphi-Quellcode:
procedure TForm1.sp_rechneClick(Sender: TObject);
var Tage_gedient, Tage_noch: integer;
   
begin

//Überprüfung Felder
If (e_eintritt.Text='') OR (e_dze.Text='') then
begin
 ShowMessage('Bitte das Eintrittsdatum und DZE ausfüllen');
 exit;
end
else


//ab hier ist die validierung okay
 begin

   //Berechnung der Tage
   diensteintritt:=StrToDate(e_eintritt.Text);
   dze:=StrToDate(e_dze.Text);
   heute:=now;
   Tage_noch:= DaysBetween(heute, dze);
   Tage_gedient := DaysBetween(diensteintritt, heute);
  l_2eintritt.Caption:='Du hast seit deinem Dienstantritt am ';
  l_zeit.Caption:=IntToStr(Tage_gedient)+ ' Tage gedient und musst noch';
  l_muil.Caption:=IntToStr(Tage_noch)+' Tage dienen!';
Ich bekomme die ANzahl der Tage als Integer zurück. Hmm aber wie mach ich daraus nun die Aufspaltung in Jahre, Monate, Tage usw zusammen mit einem laufenden Timer...

Und die Funktion die mir angeblich den genauen Wochentag anhand eines Datums zurückgibt geht auch nur mit dem "now" - sobald ich da selbst ein Datum im Format TT.MM.JJJJ eingebe ists murks.

Date, TDate, TDateTime usw machen mich noch ganz durcheinander. Mit welchem Format kann ich denn jetzt die Eingaben des Editfeldes miteinander "verrechnen" und nacher das Ergebnis entwsprechend formatieren???

liebe Grüsse aus Euskirchen


JJ

dahead 3. Aug 2005 15:19

Re: Dienstzeitende Rechner
 
ich würde entweder TDateTime oder TTimeStamp verwenden.

hier mal ein kleines beispiel, vielleicht kannst du damit was anfangen.

hinweis: wie du siehst, vergleiche ich aTimeStamp immer mit Now. Du musst now nur durch deine zweite Zeit ersetzen.
(ich weiß, ist nicht ideal, dass ich den TTimeStamp erst ins TDateTime format umwandle, aber ich hoffe du kannst dennoch daraus ableiten, wie man ein datum in tage usw. aufsplittet).

Delphi-Quellcode:
function GetDateTimeDiff(const aTimeStamp: TTimeStamp): String;
var
  Days, Hours, Minutes, Secs: Integer;
  DStr, HStr, MStr, SStr: String;
  Difference: Double;
  //LiesInPast: Boolean;
  DaysStr, HoursStr, MinutesStr, SecsStr, FmtStr: String;
begin
  Difference := TimeStampToDateTime(aTimeStamp) - Now;
  Days       := Round(Difference - Frac(Difference));
  Difference := Frac(Difference) * 24;
  Hours      := Round(Difference - Frac(Difference));
  Difference := Frac(Difference) * 60;
  Minutes    := Round(Difference - Frac(Difference));
  Difference := Frac(Difference) * 60;
  Secs       := Round(Difference - Frac(Difference));

  //LiesInPast := (Secs < 0);

  if (Days > 1) or (Days < - 1) then
   DaysStr := 'Tage'
  else
   DaysStr := 'Tag';

  if (Hours > 1) or (Hours < - 1) then
   HoursStr := 'Stunden'
  else
   HoursStr := 'Stunde';

  if (Minutes > 1) or (Minutes < - 1) then
   MinutesStr := 'Minuten'
  else
   MinutesStr := 'Minute';

  if (Secs > 1) or (Secs < - 1) then
   SecsStr := 'Sekunden'
  else
   SecsStr := 'Sekunde';

  // Nullen voranstellen
  DStr := IntToZeroStr(Days,   1);
  HStr := IntToZeroStr(Hours,  1);
  MStr := IntToZeroStr(Minutes, 2);
  SStr := IntToZeroStr(Secs,   2);

  // Vorzeichen erstellen: Negativ oder Positiv
  if Secs < 0 then
   FmtStr := '-'
  else
   FmtStr := '+';

  // Wenn 0 Tage oder 0 Std. oder 0 Min dann nicht anzeigen
  if Days <> 0 then
   FmtStr := Format('%s %s %s', [FmtStr, DStr, DaysStr]);
  if Hours <> 0 then
   FmtStr := Format('%s %s %s', [FmtStr, HStr, HoursStr]);
  if Minutes <> 0 then
   FmtStr := Format('%s %s %s', [FmtStr, MStr, MinutesStr]);
  if Secs <> 0 then
   FmtStr := Format('%s %s %s', [FmtStr, SStr, SecsStr]);

  Result := FmtStr;
end;

function IntToZeroStr(const Value, Digits: Integer): String;
var
  tmpRes: String;
begin

  if Value < 0 then
  tmpRes := IntToStr(Value * - 1) else
  tmpRes := IntToStr(Value);

  while Length(tmpRes) < Digits do
   tmpRes := '0' + tmpRes;

  Result := tmpRes;

end;
edit: hier vielleicht noch was brauchbares:

Delphi-Quellcode:

type
  TTimeStampFormat = (tsDate, tsTime, tsBoth);

function FormatTimeStamp(const aTimeStamp: TTimeStamp; TimeStampFormat: TTimeStampFormat): String;
begin
 case TimeStampFormat of
  tsDate: Result := FormatDateTime('dddddd', TimeStampToDateTime(aTimeStamp));
  tsTime: Result := FormatDateTime('tt',    TimeStampToDateTime(aTimeStamp));
  tsBoth: Result := FormatDateTime('c',     TimeStampToDateTime(aTimeStamp));
 end;
end;
im grunde, wenn du nicht mit TTimeStamp arbeiten willst, kannst du mal nach EncodeDateTime, bzw. DecodeDateTime suchen. da findest du sicherlich auch einiges an info.

s14 3. Aug 2005 15:21

Re: Dienstzeitende Rechner
 
Hallo,
es gibt die Unit "DateUtils", die enthält noch viele weitere Routinen wie "YearsBetween", usw...

Da ist bestimmt was für Dich dabei.

Ajintaro 4. Aug 2005 09:04

Re: Dienstzeitende Rechner
 
Hallo!

Danke für die Tips. Ich habe mich zuerst mal mit den DateUtils befasst - das Erbegnis ist eine sehr schwammige Milchmädchenrechnung:

Delphi-Quellcode:
procedure TForm1.sp_rechneClick(Sender: TObject);
var
    Jahre_gedient,
    Monate_gesamt, Monate_effektiv,
    Tage_gesamt, Tage_effektiv: integer;

begin

//Überprüfung Felder
If (e_eintritt.Text='') OR (e_dze.Text='') then
begin
 ShowMessage('Bitte das Eintrittsdatum und DZE ausfüllen');
 exit;
end
else

//ab hier ist die validierung okay
 begin

   //Speicherung der Daten in Variablen
   diensteintritt:=StrToDate(e_eintritt.Text);
   dze:=StrToDate(e_dze.Text);
   heute:=now;

   //Eigentliche Berechnung
   //--> hier: die vergangenen Jahre von Eintritt bis heute
   Jahre_gedient:= YearsBetween(diensteintritt, heute);

    //--> hier: die gedienten Monate abzüglich der Jahre
    Monate_gesamt := MonthsBetween(diensteintritt, heute);
    Monate_effektiv:= (Monate_gesamt) - (Jahre_gedient*12);

   //--> hier: die vergangenen Tage (ohne Schaltjahr!)
   Tage_gesamt := DaysBetween(diensteintritt, heute);
   Tage_effektiv:= ((Tage_gesamt) - (Jahre_gedient*365)) - (Monate_effektiv*30);

  l_2eintritt.Caption:='Du hast seit deinem Dienstantritt am '+ e_eintritt.Text;
  l_jahre.Caption:=IntToStr(Jahre_gedient)+' Jahr(e), '+ IntToStr(Monate_effektiv)+' Monate';
  l_zeit.Caption:=IntToStr(Tage_effektiv)+ ' Tage,';

 end;
end;//END IF
Die Anzahl der Jahre und Monate sind exakt, nur ab den Tagen wirds schwierig denn ich muss noch irgendwie die Schaltjahre mit berücksichten o.O Evt. sollte ich mir mal den Code von dahead näher anschauen.
*grübel*

mschaefer 4. Aug 2005 09:37

Re: Dienstzeitende Rechner
 
Hm, irgendwie denke ich, dass es nicht gerade kariereförderlich ist wenn sowas mal der Vorgesetzte zu Gesicht bekommt.
Ob Du Deinem Freund da wirlich was gutes tust bezweifel ich...

Eher wohl mehr als Lernprojekt gedacht...

Grüße // Martin

s14 4. Aug 2005 09:51

Re: Dienstzeitende Rechner
 
Hallo,
mit festgelegten Werten solltest Du nicht arbeiten "(Jahre_gedient*365)) - (Monate_effektiv*30);".

Wenn dich nur die verbleibenden Tage interessieren sollte es irgendwas in dieser Richtung sein:

Delphi-Quellcode:
var
  eintritt, tmp: TDateTime;
  d, m, y: Word;
begin
  y := 1999;
  m := 7;
  d := 30;
  eintritt := EncodeDateTime(y, m, d, 1, 1, 1, 1);
//  showMessage(DateToStr(eintritt));

  tmp := EncodeDate(YearOf(now), MonthOf(eintritt), DayOf(eintritt));
//  showMessage(DateToStr(tmp));


  if DayOfTheMonth(eintritt) < DayOfTheMonth(now)
    then showmessage(format('Tage: %d', [DayOfTheMonth(now) - DayOfTheMonth(eintritt)]))
    else showmessage(format('Tage: %d', [DaysBetween(tmp, now)]));
sollte sogar funktionieren :stupid:

glkgereon 4. Aug 2005 09:55

Re: Dienstzeitende Rechner
 
also spontan würde ich das so machen:

Delphi-Quellcode:
procedure Form1.Timer1OnTimer(Sender: TObject);
var Eintritt, Ende, Bisher, Rest: TDateTime;
    sBisher, sRest: String;
begin
  Eintritt:=StrToDateTime(Edt_Eintritt.Text);
  Ende:=StrToDateTime(Edt_Ende.Text);
  Bisher:=Date - Eintritt;
  sBisher:=DateToStr(Bisher);
  RestDauer:=Ende - Date;
  sRest:=DateToStr(RestDauer);
  Lbl_Anzeige.Caption:='Gedient: '+sBisher+', Rest: '+sRest;
end;
das ganze könnte man dann noch in die Wortform bringen, zb hiermit (nicht optimal vermute ich, aber es sollte gehen):

Delphi-Quellcode:
uses DateUtils;

function TimeSpan2HumanReadeable(Start, Stop: TDateTime):String;
begin
  Result:=IntToStr(YearsBetween(Start,Stop))+' Jahre, '+
          IntToStr(MonthsBetween(Start,Stop) Mod 12)+' Monate, '+
          IntToStr(DaysBetween(Start,Stop) Mod DaysInMonth(MonthsBetween(Start,Stop) Mod 12))+' Tage, '+
          IntToStr(HoursBetween(Start,Stop) Mod 24)+' Stunden, '+
          IntToStr(MinutesBetween(Start,Stop) Mod 60)+' Minuten, '+
          IntToStr(SecondsBetween(Start,Stop) Mod 60)+' Sekunden';
end;

marabu 4. Aug 2005 10:18

Re: Dienstzeitende Rechner
 
Hallo JJ,

Zitat:

Zitat von Ajintaro
das Erbegnis ist eine sehr schwammige Milchmädchenrechnung

hast du auch schon mal hier geschaut?

Grüße vom marabu

oaj47

Ajintaro 4. Aug 2005 13:36

Re: Dienstzeitende Rechner
 
Juchuuuuu!!!!!

Das waren die finalen Tips :)) Nun läuft das Lehrprogramm und alle sind happy :)

Vielen Dank!


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:18 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