Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Arbeitstage berechnen (https://www.delphipraxis.net/38878-arbeitstage-berechnen.html)

LogoPie 25. Jan 2005 15:57


Arbeitstage berechnen
 
Hallo Leutz

Ich möchte anhand von von zwei Daten sprich z.B. 02.01.05 und 12.02.05
die Arbeitz bzw. die Urlaubstage Berechnen.
Wie stelle ich das an hat jemand ein Beispiel.
Natürlich ohne Wochendende und Feiertage.

Sharky 25. Jan 2005 15:59

Re: Arbeitstage berechnen
 
Hai LogoPie,

als erstes brauchst Du eine Liste aller Feiertage (abhängig vom Bundesland) Dann könntest Du einfach in einer Schleife prüfen ob das Datum X ein Arbeitstag ist.

toms 25. Jan 2005 16:00

Re: Arbeitstage berechnen
 
Delphi-Quellcode:
Function NumWorkDays( StartDate,EndDate:TDateTime):LongInt;
Var Workdays:LongInt;
Begin
  WorkDays := 0;
  While StartDate <= EndDate do Begin
    If DayOfWeek(StartDate) in [2..6] Then
       Inc( WorkDays );
    StartDate := StartDate + 1;
  End;
  Result := WorkDays;
End;
(Feiertag Pruefung muss noch eingebaut werden)

LogoPie 26. Jan 2005 10:11

Re: Arbeitstage berechnen
 
schon mal vielen dank,
Aber wie krieg ich das in mein Programm.
Habe drei TEdit felder.
In die ersten beiden soll der Benutzer das Datum von bis eingeben (12.01.05 bis 29.01.05)
Die Rechnung soll durch einen Button ausgelöst werden.
Ergebnis soll im dritten Edit angezeit werden.
Ergebnis wäre 13 Urlaubstage ohne Wochenende [2..6]
gruß LogoPie

Sharky 26. Jan 2005 10:15

Re: Arbeitstage berechnen
 
Hai LogoPie,

ich würde für die Datumseingabe keine Edits nehmen sonder TDateTiemPicker. Dann einfach mit dem Code von toms:

Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
begin
  EditTage.Text := IntToStr (NumWorkDays (DateTimePicker1.Date,DateTimePicker2.Date));
end;

LogoPie 26. Jan 2005 11:43

Re: Arbeitstage berechnen
 
Juhu klappt wunder bar
Hier mal das Gesamtergebnis für alle anderen.
Delphi-Quellcode:
Function Arbeitstage( Beginn,Ende:TDateTime):LongInt;
Var Tage:Integer;    
    i  :Integer;
Begin
  Tage := 0;
  i   := 1;
  While Beginn <= Ende do Begin    
    If DayOfWeek(Beginn) in [2..6] Then    
    Inc( Tage );
    Beginn := Beginn + i;
  End;
  Result := Tage;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
     EditTage.Text := IntToStr (Arbeitstage (Beginn.Date,Ende.Date));
end;

end.
Nun stehe ich schon vor dem nächsten Problem
das heißt es ist nur ein kleines.
Das einbinden von Feiertagen.
Bei festen Tagen wie Silvester oder Weihnachten sollte es keine Probleme geben,
aber wie berechne ich z.B Pfingsten oder Ostern.

Treffnix 26. Jan 2005 11:49

Re: Arbeitstage berechnen
 
Für Ostern gibt es hier eine Funktion von Flomei. Pfingsten lässt sich glaube ich aus Ostern berechnen ( + 40 Tage oder so? :gruebel: ). Karfreitag ist Ostersonntag - 2, Ostermontag ist logischerweise Ostersonntag + 1 ( :shock: ).
Heiligabend, Weihnachten, Silvester, 1.Mai sind dagegen wahnsinnig kompliziert :zwinker:

*edit* mir fällt gerade ein, dass das mit den 40 Tagen die Fastenzeit war, und 40 Tage nach Ostern auch gar kein Wochenende ist, aber Pfingsten ist afair auch irgendwie abhängig von Ostern.

kiar 26. Jan 2005 11:55

Re: Arbeitstage berechnen
 
schau bei den schweizern

http://www.swissdelphicenter.ch/de/showcode.php?id=1278

raik

Sharky 26. Jan 2005 11:56

Re: Arbeitstage berechnen
 
Hai,

wie Treffnix schon sagte sind die meisten Kirchlichen-Feiertage von Ostern abgeleitet. Dafür findest Du sicher eine Liste.
Aber wie ich schon sagte: Du musst die Regelungen der einzelnen Bundesländer beachten.

kiar 26. Jan 2005 12:01

Re: Arbeitstage berechnen
 
und hier noch ne erweiterung

http://www.swissdelphicenter.ch/de/f...sche+feiertage

raik

LogoPie 26. Jan 2005 12:15

Re: Arbeitstage berechnen
 
Danke euch :thumb:
werd später dann wieder das ergebnis Posten, :coder2:
wenn mir nicht vorher die Birne platzt. :wall:

LogoPie 26. Jan 2005 14:06

Re: Arbeitstage berechnen
 
Halt Stop bevor sich jemand die mühe macht zu schreiben.
Hab da noch ne Idee.

LogoPie 26. Jan 2005 14:18

Re: Arbeitstage berechnen
 
Wie so oft nur ne kleinigkeit :roll:

Hier nun das Ergebnis
Unit 1
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

uses Unit2, Feiertage;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var hdays : THolidayTable;
    i    : Integer;
  //  j    : Integer;
begin
     hdays:=GetHolidayTable(2005);
   //  Edit1.Text := IntToDate(j);
     listbox1.items.Clear;
     for
        i:=0 to high(hdays)do
        listbox1.items.Add(DateToStr(hdays[i].date)+' '+hdays[i].name);
end;

end.
Wie sicher schon jemand bemerkt hat habe ich versucht das Jahr über ein Editfeld einzugeben
mit mäßigem erfolg. Habe diverse Datentypen probiert, aber immer flogen mir neue Fehlermeldungen an
den Kopf. Vielleicht weiß ja jemand eine Lösung. Meist ging es um konfligte mit Date und Word.

Unit 2
Delphi-Quellcode:
unit Unit2;

interface

uses Windows, SysUtils;

type
    THoliday = Record
        Date: TDateTime;
        Name: String;
    End;
    THolidayTable = Array Of THoliday;

    Function GetHolidayTable(Year: Word): THolidayTable;

implementation

Function GetHolidayTable(Year: Word): THolidayTable;

    Procedure AddHoliday(DD, MM: Word; HDName: String); Overload;
    Begin
        SetLength(Result, High(Result) + 2);
        With Result[High(Result)] Do
        Begin
            Date := EncodeDate(Year, MM, DD);
            Name := HDName;
        End;
    End;

    Procedure AddHoliday(HDDate: TDateTime; HDName: String); Overload;
    Begin
        SetLength(Result, High(Result) + 2);
        With Result[High(Result)] Do
        Begin
            Date := HDDate;
            Name := HDName;
        End;
    End;

    Function GetEasterDate(YYYY: Word): TDateTime;
    Var
        A, B, C, D, E, F, G, H, I, K, L, M, N, P: Word;
        DD, MM: Word;
    Begin
        a := YYYY Mod 19;
        b := YYYY Div 100;
        c := YYYY Mod 100;
        d := b Div 4;
        e := b Mod 4;
        f := (b + 8) Div 25;
        g := (b - f + 1) Div 3;
        h := (19 * a + b - d - g + 15) Mod 30;
        i := c Div 4;
        k := c Mod 4;
        l := (32 + 2 * e + 2 * i - h - k) Mod 7;
        m := (a + 11 * h + 22 * l) Div 451;
        n := (h + l - 7 * m + 114) Div 31;
        p := (h + l - 7 * m + 114) Mod 31 + 1;
        DD := p;
        MM := n;
        Result := EncodeDate(YYYY, MM, DD);
    End;
Var
    EDate: TDateTime;
Begin
    AddHoliday(1, 1, 'Neujahr');
    AddHoliday(1, 5, 'Tag der Arbeit');
    AddHoliday(3, 10, 'Tag der deutschen Einheit');
    AddHoliday(25, 12, '1. Weihnachtsfeiertag');
    AddHoliday(26, 12, '2. Weihnachtsfeiertag');
    AddHoliday(1, 11, 'Allerheiligen');
    EDate := GetEasterDate(Year);
    AddHoliday(EDate + 60, 'Fronleichnam');
    AddHoliday(EDate - 2, 'Karfreitag');
    AddHoliday(EDate + 1, 'Ostermontag');
    AddHoliday(EDate + 39, 'Christi Himmelfahrt');
    AddHoliday(EDate + 50, 'Pfingstmontag');
End;

end.

LogoPie 26. Jan 2005 16:03

Neu Arbeitstage berechnen
 
siehe einen darüber

shmia 26. Jan 2005 16:47

Re: Arbeitstage berechnen
 
Also ich würde die Feiertagsliste vom Zählen der Arbeitstage getrennt halten.
Dies lässt sich mit einer Callback-Funktion erreichen.
siehe auch Code-Library: http://www.delphipraxis.net/internal...ct.php?t=22228

Delphi-Quellcode:
type
// callback function for holidays
THolidayCallback = function(const d:TDateTime):boolean;

function NumWorkDays(StartDate,EndDate:TDateTime; callback:THolidayCallback):Integer;
Begin
   Result := 0;
   While StartDate <= EndDate do
   begin
      If (DayOfWeek(StartDate) in [2..6]) and not callback(StartDate) Then
         Inc(Result);
      StartDate := StartDate + 1;
  End;
End;

LogoPie 27. Jan 2005 08:21

Re: Arbeitstage berechnen
 
Blöd ist nur das sich das Datum direkt im Quelltext befinden muss.
Hab schon einige male probiert es über ein Textfeld abzufragen aber,
es tauchen immer wieder konflikte auf.
Vielleicht kann mir jemand den entscheidenen Tip geben.

Sharky 27. Jan 2005 08:30

Re: Arbeitstage berechnen
 
Zitat:

Zitat von LogoPie
Blöd ist nur das sich das Datum direkt im Quelltext befinden muss....

Welches Datum muss ich im Quelltext befinden?

LogoPie 27. Jan 2005 08:41

Re: Arbeitstage berechnen
 
Args Sorry nich das Datum das Jahr für die Berechnung meinte ich.

LogoPie 27. Jan 2005 09:39

Re: Arbeitstage berechnen
 
So hat hingehauen
Delphi-Quellcode:
year : Integer;
begin
     year := StrToInt (Edit1.Text);
     hdays:=GetHolidayTable(year);

stoxx 23. Mai 2009 13:45

Re: Arbeitstage berechnen
 
Ergänzung Ostersonntag:

Zitat Wikipedia:

Zitat:

Obwohl die Gaußsche Osterformel den Oster-Algorithmus elegant kurz darstellt, werden zwei Ausnahmen von ihr nicht erfasst. Heiner Lichtenberg hat 1997 eine Modifikation der Formel vorgeschlagen, mit der keine Ausnahmen extra beachtet werden müssen. Diese Formel ist nachfolgend wiedergegeben
http://de.wikipedia.org/wiki/Gaußsche_Osterformel

1. die Säkularzahl: K(X) = X div 100
2. die säkulare Mondschaltung: M(K) = 15 + (3K + 3) div 4 − (8K + 13) div 25
3. die säkulare Sonnenschaltung: S(K) = 2 − (3K + 3) div 4
4. den Mondparameter: A(X) = X mod 19
5. den Keim für den ersten Vollmond im Frühling: D(A,M) = (19A + M) mod 30
6. die kalendarische Korrekturgröße: R(D,A) = D div 29 + (D div 28 − D div 29) (A div 11)
7. die Ostergrenze: OG(D,R) = 21 + D − R
8. den ersten Sonntag im März: SZ(X,S) = 7 − (X + X div 4 + S) mod 7
9. die Entfernung des Ostersonntags von der
Ostergrenze (Osterentfernung in Tagen): OE(OG,SZ) = 7 − (OG − SZ) mod 7
10. das Datum des Ostersonntags als Märzdatum
(32. März = 1. April usw.): OS = OG + OE


hier habe ich folgenden Code nach dieser Formel gefunden:


http://cerebrumsoft.org/node/54

Delphi-Quellcode:
(* Hucke
   Berechnung des Ostersonntag
   Algorithmus nach Gauß
   modifiziert von Lichtenberg
   aus: Wikipedia "Gaußsche Osterformel" 26.02.2008
*)
 
uses
    sysutils;
 
function EasterSunday_Lichtenberg(const Jahr :integer): TDateTime;
var
    k, // Säkularzahl  säkular = weltlich im Gegensatz zu kirchlich
    m, // säkulare Mondschaltung
    s, // säkulare Sonnenschaltung
    a, // Mondparameter
    d, // erster Vollmond im Frühling
    r, // kalendarische Korrekturgröße
    og, // Ostergrenze
    sz, // erster Sonntag im März
    oe, // Differenz Ostersonntag Ostergrenze (Osterentfernung)
    os, // Ostersonntag als Märzdatum
    tag,
    monat : integer;
 
begin
    k := Jahr div 100;
    m := 15 + (3 * k + 3) div 4 - (8 * k + 13) div 25;
    s := 2 - (3*k + 3 ) div 4;
    a := Jahr mod 19;
    d := (19 * a + m ) mod 30;
    r := d div 29 + (d div 28 - d div 29) * (a div 11);
    og := 21 + d - r;
    sz := 7 - (Jahr + Jahr div 4 + s ) mod 7;
    oe := 7 - (og - sz) mod 7;
    os := og + oe;
 
    if os <= 31 then begin
       Tag := os;
       Monat := 3;
    end
    else begin
       Tag := os - 31;
       Monat := 4;
    end;
 
    result := encodedate(jahr, Monat, Tag);
 
end;


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