Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » Algorithmen » Datumsberechnung » Antwort erstellen » Hallo Gast [Anmelden|Registrieren]

Antwort erstellen
Benutzername: (du bist nicht eingeloggt!)
Thema:
Nachricht:

HTML ist nicht erlaubt
BBCode ist erlaubt
Smilies sind erlaubt
Bilder sind erlaubt

Smilies: 21 von 33
smileWinkDaumen hoch
verwirrtAugenzwinkerngeschockt
Mit ZungeGottunglücklich
Forum Kloppebösegroßes Grinsen
TanzentraurigProst
TeufelSpamWillkommen
LehrerLOL HammerZunge raus
Hilfe 
aktuellen Tag schließen
alle Tags schließen
fettgedruckter Textkursiver Textunterstrichener Text zentrierter Text Hyperlink einfügenE-Mail-Adresse einfügenBild einfügen Zitat einfügenListe erstellen CODE einfügenPHP CODE farbig hervorheben
Spamschutz:
Text aus Bild eingeben
Spamschutz

Die letzten 8 Beiträge
as_string

Klar, ok, Hochzählen geht natürlich auch...
Früher, in meiner Jugend..., als ich noch C programmiert hab, hat man meistens den Zähler mit der "Ziel-Zahl" initialisiert und dann runter gezählt. Solange er noch größer 0 war (also while(counter), wenn counter == 0, dann ist der Ausdruck false und while bricht ab) hat man dann geschaut, ob counter verringert werden muss oder nicht.
Aber das ist natürlich reine Geschmackssache.
Daumen hoch

Gruß
Marco
c.i.b.magic

Danke !!!! Ich hab's !
Kann mich erst jetzt melden, da ich krank war. Der Post von as_string hat mir endlich die Augen geöffnet.

Hier meine Lösung (ist PHP-Syntax, ich hoffe Ihr kommt damit klar - ansonsten bei Interesse fragen)

php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
// Variablen die an anderer Stelle deklariert werden
// $feiertage = ein Array von Datum in der Form YYYY-MM-DD
// $ausgabetage = ein Array der Wochen-Liefertage des Lieferanten in der Form von 0 bis 6
// $whvorlauf = die Anzahl der Vorlauftage als Int

    $tage=0;
    $tempdat=new DateTime('NOW');
    $wochenende=array(0,6);
    while($tage<$whvorlauf) {
      $str="1 day";
      date_modify($tempdat,$str);
      $tagderwoche=date_format($tempdat,'w');
      $tagesdatum=date_format($tempdat,'Y-m-d');
      if(in_array($tagderwoche,$wochenende) || in_array($tagesdatum,$feiertage)) $whvorlauf++;
      $tage++;
    }
    while(!in_array(date_format($tempdat,'w'),$ausgabetage) || in_array(date_format($tempdat,'Y-m-d'),$feiertage)) {
      $str="1 day";
      date_modify($tempdat,$str);
    }
    $fruehest=date_format($tempdat,'d.m.Y');


Vielen Dank an alle, die sich für mich bemüht haben !!!
Stephan
as_string

Warum so kompliziert mit temp_lieferdatum und dann ein dynamisch anpassendes Schleifenende?
Einfach einen Zähler mit den Vorlauftagen initialisieren. Dann eine while-Schleife, die ab heute los läuft und so lange checkt, ob die Tage gültige Werktage sind und den Zähler runter zählt, bis ausreichend gültige Vorlauf-Werktage gefunden sind.
Ab hier dann wieder Suche nach dem nächsten gültigen Liefertag. Das könnte man auch sequenziell Tag für Tag machen, oder man überlegt sich hier was von wegen: Wochentage Montag bis Freitag in einer Reihe Zahlen vergeben, wenn kein höherer Liefertag (in dieser Woche) findbar, nimm ersten Liefertag in der nächsten Woche.

Die Frage ist nur, ob man es irgendwie optimieren könnte, so dass man die Schleife über die Vorlaufzeit nicht bräuchte. Aber was soll man da bitte groß gewinnen können? Das werden ja nicht so häufig mehr als 5 Tage Vorlaufzeit sein und selbst ein paar Hundert hätte ein Rechner ziemlich schnell abgearbeitet. Letztlich muss man sich ja doch jeden einzelnen Tag anschauen, besonders wenn man auch Feiertage berücksichtigen muss.

Gruß
Marco
NixJava

Straightforward würde ich es so lösen:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
bestelldatum := date(now);
temp_lieferdatum := bestelldatum + vorlauftage;

/* temp_lieferdatum ist der frühstmögliche Liefertermin unter
Berücksichtigung der Vorlauftage, aber ohne Berücksichtigung
der Wochenenden bzw. Feiertage. */


/* Im Folgenden werden die Wochenenden und Feiertage berücksichtigt. */

For Each tag In (bestelldatum, temp_lieferdatum) {
  if (tag.get_wochentag() == 'SA' oder 'SO' oder Feiertag) {
    temp_lieferdatum++;
  }
  /* Wichtig ist, dass die Schleifengrenze (temp_lieferdatum)
  dynamisch angepasst wird. */
}

/* Der frühstmögliche Liefertermin unter Berücksichtigung der Vorlaufzeit samt 
Wochenenden wurde ermittelt. Jetzt noch den nächsten legalen Liefertag berechnen. */

while (temp_lieferdatum.get_wochentag() != liefertag) {
  temp_lieferdatum++;
}

lieferdatum := temp_lieferdatum;
c.i.b.magic

Ergänzung :

außerdem berücksichtigt dein Codeschnipsel folgendes nicht :

Was ist, wenn der berechnete Zieltag kein gültiger Liefertag ist -> dann müsste bis zum nächst möglichen Liefertag weitergerechnet werden.
Und: angenommen, der berechnete Zieltag wäre ein Dienstag, der Lieferant liefert aber nur Montags - dann müsste weiter berechnet werden, wobei wiederum ein WE dazwischen liegt.
c.i.b.magic

Hi ED,

danke das Du dich meldest !

Zitat:
Original von ed209
Zwei Fragen:

1.) Was ist der Unterschied zwischen Vorlauftagen und Liefertagen?
2.) Verhalten sich Feiertage wie Wochenenden?


Also, als Liefertag meine ich den WOCHENtag, also Montag, Dienstag usw.
Wie beschrieben kann ein Lieferant 1 bis n=5 Liefertage haben.

Die Vorlauftage sind die Tage, die zwischen Bestellung und frühest möglichen Liefertag liegen müssen (also die Zeit, die der Lieferant zur Kommissionierung der bestellten Artikel benötigt)

Die Wochenenden zählen nicht mit, da die Lieferanten an diesen Tagen nicht arbeiten. Daher zählen sie auch nicht mit in die Vorlauftage, da am Wochenende nicht kommissioniert werden kann. (Feiertage ebenfalls, aber die ignoriere ich zunächst, obwohl ich mir die auch aus eines DB ziehen könnte).

Dein Code ist zunächst verständlich, aber wenn ich nur die Werktage zähle, wie komme ich dann auf ein gültiges Datum. Erhalte ich 5 Tage zurück, aber ein WE liegt dazwischen, kann ich nicht heute()+Tage addieren

hmm, allerdings könnte man die Wochenenden mitzählen und mal 2 rechnen
... ist eine Überlegung wert.

Danke nochmals, wenn Du weitere Ideen hast, immer her damit :-)

Stephan
ed209

Zwei Fragen:

1.) Was ist der Unterschied zwischen Vorlauftagen und Liefertagen?
2.) Verhalten sich Feiertage wie Wochenenden?

EDIT: Waehrend wir warten kann ich ja mal auf das was ich als das Kernproblem sehe eingehen:

Zitat:

3. Der Lieferant kann frei wählen, wie viele Tage zwischen Bestellung und frühestem Liefertag liegen müssen (0 bis n) [Vorlauftage]
4. Wochenenden (Sa+So) verlängern, aber nur bei Überschneidung, die Frist der Vorlauftage


Diese Formulierung ist etwas umstaendlich und lenkt dich ein bisschen in eine falsche Richtung:

Zitat:

=> Freitag+2 Vorlauftage = Sonntag(ungültig !!!) => Montag; Montag ist ein gültiger Liefertag, aber da zwei WochenENDtage dazwischen liegen

Es sieht so aus als wuerdest du die Kalendartage hochzaehlen und dann die Wochenendtage runterzaehlen. Viel einfacher waere es wenn du einfach die Werktage hochzaehlst.

Zitat:

3. Der Lieferant kann frei wählen, wie viele Werktage zwischen Bestellung und frühestem Liefertag liegen müssen (0 bis n) [Vorlauftage]


Hier mal etwa Pseudocode:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
berechne_ersten_tag_mit_genug_vorlaufzeit(heute, vorlauftage):
    tage = 0 
    naechster_tag = heute
    while tage < vorlauftage:
        naechster_tag = naechster_tag + 1
        if (naechster_tag ist ein werktag):
           tage = tage + 1
    return naechster_tag


Gruss,
ED
c.i.b.magic Datumsberechnung

Hallo Community,

dieser Algorithmus verfolgt mich seit Jahren, meine derzeitige Lösung funktioniert zwar, aber nicht in allen Fällen. Und das macht mich alle.
Jetzt schreibe ich die Applikation neu, und jetzt hätte ich gerne eine 100%-logische Lösung.

Ich entwickle jetzt in PHP, es geht mir aber nicht um eine PHP-Lösung (wäre natürlich toll) sondern um eine, alle Nebenbedingungen abdeckende, Lösung.

Hier die Problematik:
Gegeben ist ein Bestellformular, auf dem der User auswählen kann, zu welchem Datum er die Lieferung erhalten möchte. Dabei soll der User die Wahl aus unterschiedlichen, gültigen (!!!!) Lieferdaten haben

Folgende Nebenbedingungen bestehen:
1. Das Datum der Bestellung = heute()
2. Die möglichen Liefer-WOCHENTAGE, die der Lieferant frei wählen kann
2.1 Der Lieferant kann zwischen 1 und n Liefertagen wählen (n=Tmax=5)
2.2 Die Liefertage liegen zwischen Montag und Freitag
3. Der Lieferant kann frei wählen, wie viele Tage zwischen Bestellung und frühestem Liefertag liegen müssen (0 bis n) [Vorlauftage]
4. Wochenenden (Sa+So) verlängern, aber nur bei Überschneidung, die Frist der Vorlauftage
5. Ist die Summe der Vorlauftage<dem frühestmöglichen Liefertag, muss sich dieser auf den nächstmöglichen (erlaubten) Liefertag ändern
6. Entgegen der erlaubten Liefertage des Lieferanten, kann ein User an allen 7 Tagen der Woche bestellen

Die Problematik besteht vor allem in der Wahl der Anzahl der Wochentage (Lieferant A liefert nur Dienstags - B Montag, Mittwoch und Freitag - C an jedem Werktag).

Die "einfache" Berechnung bekomme ich problemlos hin - aufgeben muss ich leider bei der Berücksichtigung der Vorlauftage PLUS Wochenendberechnung.

Beispiel:
Der Lieferant liefert nur Donnerstag, braucht zwei Tage Vorlaufzeit.
a) Ein User bestellt Montags
=> Montag+2 Tage Vorlauf = Mittwoch < Donnerstag => der KOMMENDE Donnerstag ist der erste gültige Liefertag; weitere Liefertage sind dann DO eine Woche später usw.
b) Ein User bestellt Mittwoch
=> Mittwoch+2 Tage Vorlauf = Freitag > Donnerstag => der Donnerstag DER NÄCHSTEN WOCHE ist der erste gültige Liefertermin; weitere ....
c) Ein User bestellt Freitag
=> Freitag+2 Tage Vorlauf = Sonntag (ups, Wochenende)
[US-Software] Sonntag<Freitag - *grr* [krieg ich aber hin]
In diesem Fall nicht schlimm, weil nach wie vor b) gilt

Der Lieferant liefert nur Montag, 2 Tage Vorlaufzeit
a) Problemlos, wenn der User bis Donnerstag bestellt, aber :
b) Der User bestellt Fr(Sa/So)
=> Freitag+2 Vorlauftage = Sonntag(ungültig !!!) => Montag; Montag ist ein gültiger Liefertag, aber da zwei WochenENDtage dazwischen liegen, ist die Vorlaufzeit nicht gegeben => frühester Liefertag Montag eine Woche später

Das ganze wird halt noch spannender, wenn es mehrere Wochentage zur Lieferung gibt - und vor allem (!!) - wenn die Vorlaufzeit so hoch gewählt wird, das gleich mehrere Wochenenden überschnitten werden (könnten) [Bspw. VLZ=10].

---

Ich hasse Datum !!! :o)
Es wäre richtig toll, wenn sich der eine oder andere von Euch an dieses Konstrukt wagen würden (ich hoffe, ihr flucht dabei nicht so, wie ich es derzeit tue).

Wäre auf jeden Fall klasse, eine Antwort zu bekommen!!!

Danke
Stephan