Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Berechnungen mit Arbeitstagen (https://www.delphipraxis.net/142450-berechnungen-mit-arbeitstagen.html)

Fridolin 28. Okt 2009 11:39


Berechnungen mit Arbeitstagen
 
Hallo zusammen,

ich habe folgendes Problem:

Ich möchte von einem Datum eine Anzahl x Tage substrahieren. Das besondere dabei ist, dass in der Berechnung die Wochenenden übersprungen werden sollen.

Wenn also z.B. der 22.09.2009 das Enddatum ist (am Ende des Tages ist das Projekt abgeschlossen) und ich nun Rückwerts rechnen will, um zu berechnen, wann man anfangen muss, dann muss ich rechnen:

Endtermin - x = Starttermin

z.B. :

ohne Berücksichtigung der Wochenenden:
22.09.2009 - 30 = 24.08.2009

mit Berücksichtigung der Wochenenden:
22.09.2009 - 30 = 12.08.2009

Gibt es dafür evtl. eine fertige Funktion?

Ich bin für jede Hilfe sehr dankbar!

Mit freundlichen Grüßen,

Fridolin

hoika 28. Okt 2009 11:42

Re: Berechnungen mit Arbeitstagen
 
Hallo,

würde ich selber schreiben.
Delphi-Quellcode:
iMaxDays:= 10;
iDays:= 0;


tdtStartDate:= '22.09.2009';
tdtCurDate:= tdtStartDate+1.0;

repeat
  tdtCurDate:= tdtCurDate-1.0;
  if DayOfWeek(tdtCurDate)<>So and <>Sa then
  begin
    Inc(iDays);
    if iDays=iMaxDays then break;
  end;
until False;

Heiko

RWarnecke 28. Okt 2009 12:07

Re: Berechnungen mit Arbeitstagen
 
Hier ist noch ein Beitrag mit nochmehr Beispielen.

himitsu 28. Okt 2009 12:08

Re: Berechnungen mit Arbeitstagen
 
Theoretisch sollte es möglich sein, dieses auch ohne Schleife zu berechnen,
aber irgendwie wollte das gard nicht so klappen :?

- schauen wo in der Woche man sich gerade befindet
- das Datum zum Wochenanfang zurückrechnen und sich die Tage in der aktuellen Woche merken
- Restzeit durch 5 mal 7 (Ganzzahldivision ... Rest merken)
- Produkt nehmen und die gemerten Tage/Reste wieder dazurechnen
- Datum - diese Summe = Anfang
(nja, so in etwa irgendwie)


aber mit 'ner Schleife ginge es wohl auch so
(DayOfTheWeek: 1=Montag ... 7=Sonntag)
Delphi-Quellcode:
Type TDayOfTheWeekSet = Set of 1..7;

Function IncDays(D: TDateTime; Days: Integer = 1; Ignored: TDayOfTheWeekSet = [6, 7]): TDateTime;
  Var i: Integer;

  Begin
    i := 0;
    While Days > 0 do Begin
      If not (DayOfTheWeek(D + i) in Ignored) Then Dec(Days);
      Inc(i);
    End;
    While Days < 0 do Begin
      If not (DayOfTheWeek(D + i) in Ignored) Then Inc(Days);
      Dec(i);
    End;
    Result := D + i; // wegen Rundungsfehlern erst hier einrechnen
  End;

Function DecDays(D: TDateTime; Days: Integer = 1; Ignored: TDayOfTheWeekSet = [6, 7]): TDateTime;
  Begin
    Result := IncDays(D, -Days, Ignored);
  End;
[edit]
die Definition des SET vergessen :oops:

nja, wenn ich den Baitrag von marabu so seh, dann lieg ich schonmal mit meiner Überlegung nicht ganz falsch :angel:

Sherlock 28. Okt 2009 12:40

Re: Berechnungen mit Arbeitstagen
 
Ich möchte hier gerne noch in den Raum werfen, daß eigentlich auch der Samstag ein Werktag ist :(
Darum die Frage, ob das nicht parametrisierbar sein könnte, Mo-Fr oder eben Mo-Sa.

Sherlock

Fridolin 28. Okt 2009 12:46

Re: Berechnungen mit Arbeitstagen
 
Bei uns ist am Samstag (Gott sei Dank) der Laden dicht :-D .

Ich danke euch allen!

Mit himitsu Lösung hat es wunderbar funktioniert :thumb: .

Vielen Dank!

Gruß,

Fridolin

schlecki 28. Okt 2009 12:50

Re: Berechnungen mit Arbeitstagen
 
Zitat:

Zitat von Fridolin
Bei uns ist am Samstag (Gott sei Dank) der Laden dicht :-D .

Ich danke euch allen!

Mit himitsu Lösung hat es wunderbar funktioniert :thumb: .

Vielen Dank!

Gruß,

Fridolin

Mal noch ne Frage: Was ist denn mit Feiertagen? ;)

hoika 28. Okt 2009 12:53

Re: Berechnungen mit Arbeitstagen
 
Hallo,

Zitat:

Feiertage
deshalb ja auch meine Schleife.

Es soll ja Leute geben, die z.B. Montag frei haben,
dafür Samstag arbeiten.


Heiko

himitsu 28. Okt 2009 13:24

Re: Berechnungen mit Arbeitstagen
 
Mit veränderbaren Tagen wird ein Schleifenloses rechnen aber immer schwerer :nerd:


Delphi-Quellcode:
// 1=Monday ... 7=Sunday

Function IncDays(D: TDateTime; Days: Integer = 1;
  WorkingDays: TDayOfTheWeekSet = [1..5]): TDateTime;

Function IncDays(D: TDateTime; Days: Integer; WorkingDays: TDayOfTheWeekSet;
  Holidays: Array of TDateTime): TDateTime;

Function DecDays(D: TDateTime; Days: Integer = 1;
  WorkingDays: TDayOfTheWeekSet = [1..5]): TDateTime;

Function DecDays(D: TDateTime; Days: Integer; WorkingDays: TDayOfTheWeekSet;
  Holidays: Array of TDateTime): TDateTime;
Delphi-Quellcode:
Uses Math, DateUtils;

Type TDayOfTheWeekSet = Set of 1{Monday}..7{Sunday};

Function IncDays(D: TDateTime; Days: Integer = 1;
    WorkingDays: TDayOfTheWeekSet = [1..5]): TDateTime; Overload;

  Var i: Integer;

  Begin
    i := 0;
    While Days > 0 do Begin
      If DayOfTheWeek(D + i) in WorkingDays Then Dec(Days);
      Inc(i);
    End;
    While Days < 0 do Begin
      If DayOfTheWeek(D + i) in WorkingDays Then Inc(Days);
      Dec(i);
    End;
    Result := D + i;
  End;

Function IncDays(D: TDateTime; Days: Integer; WorkingDays: TDayOfTheWeekSet;
    Holidays: Array of TDateTime): TDateTime; Overload;

  Var i: Integer;

  Function isWorkingDays: Boolean;
    Var i2: Integer;
      D2: TDateTime;

    Begin
      Result := DayOfTheWeek(D + i) in WorkingDays;
      If not Result Then Exit;
      Result := False;
      D2 := Trunc(D + i);
      i2 := High(Holidays);
      While i2 >= Low(Holidays) do
        If SameValue(Trunc(Holidays[i2]), D2) Then Exit Else Dec(i2);
      Result := True;
    End;

  Begin
    i := 0;
    While Days > 0 do Begin
      If isWorkingDays Then Dec(Days);
      Inc(i);
    End;
    While Days < 0 do Begin
      If isWorkingDays Then Inc(Days);
      Dec(i);
    End;
    Result := D + i;
  End;

Function DecDays(D: TDateTime; Days: Integer = 1;
    WorkingDays: TDayOfTheWeekSet = [1..5]): TDateTime; Overload;
  Begin
    Result := IncDays(D, -Days, WorkingDays);
  End;

Function DecDays(D: TDateTime; Days: Integer; WorkingDays: TDayOfTheWeekSet;
    Holidays: Array of TDateTime): TDateTime; Overload;
  Begin
    Result := IncDays(D, -Days, WorkingDays, Holidays);
  End;


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