Rechnen Mit Datum

hhunderter

Erfahrenes Mitglied
Guten Morgen,

ich entwickle gerade ne "Art" Kalender und muss mit Tagen Rechnen...

Vorab würde ich gerne Timestamps vermeiden...

1. Wie kann man am besten auf ein Datum zb. 25.3.2012 + 60Tage -> 24.5.2012 rechnen?
2. Wie finde ich einen bestimmten Wochentag zb den 1. Sammstag im Monat 3 herraus?
 
Ist eigentlich ganz einfach.

PHP:
<?php
// Ausgangsdatum
$datum = strtotime("25.03.2012");
// 60 Sekunden * 60 Minuten * 24 Stunden = 1 Tag
$faktor = 86400;
// 60 Tage dazu zählen
$tage = 60;
// Enddatum
echo date("d.m.Y", $datum + ($tage * $faktor));

echo "<p></p>";

// Mit dem Monatsersten beginnen
$datum = strtotime("01.03.2012");
// Montag = 1, Dienstag = 2, ..., Samstag = 6, Sonntag = 0
while (date("w", $datum) != 6) {
	$datum = $datum + 86400;
}

echo "Der erste Samstag im Monat ist der " .date("d.m.Y", $datum);
?>
 
Wenn ich damit gearbeitet hätte wäre es ja einfach gewesen wie du schon sagtest aber :
Vorab würde ich gerne Timestamps vermeiden...
und meines Wissens gibt strtotime einen Timestamp zurück...

also mit dem 1. Sammstag habe ich schon hinbekommen :
(Quelle:http://www.dagmar-mueller.de/wdz/html/feiertagsberechnung.html)
PHP:
function get_day($Month,$Day,$Year)
{
    // 0 = Sonntag
    // 1 = Montag
    // 2 = Dienstag
    // 3 = Mittwoch
    // 4 = Donnerstag
    // 5 = Freitag
    // 6 = Samstag
    if ($Month < 3)
    {
        $a = ($Year - 1) * 365.25;
        $b = ($Month + 13) * 30.6;
    }
    elseif($Month > 2)
    {
        $a = $Year * 365.25;
        $b = ($Month + 1) * 30.6;
    }
    return ($a + $b + $Day - 621049) % 7;
}

Mit der 1. Frage fällt mir nur eine Lösung ein : eine Funktion zu schreiben die die Tage addiert , diese dann in einer Schleife konntroliert wieviele Tage der Monat hat und diese dann abzieht (wenn über Max_Tage_Monat)...
 
Wenn du mit Datum rechnen willst, kommst du am timestamp oder an DateTime nicht vorbei. DateTime hat seine Vorteile, ist jedoch aus meiner Sicht noch nicht komplet.
Auch timestamps haben ihre Tücken. Da muss man sich halt die Funktionalität etwas erweitern.

PHP:
define('C_DATE_FORMAT', 'd.m.Y');

$date = strtotime('25.3.2012');
$date60 = strtotime("+60 day", $date);

$samstage = findWeekdays('sat', 3, 2012);
$dateFirstMonday = $samstage[0];

var_dump(date(C_DATE_FORMAT, $date));
var_dump(date(C_DATE_FORMAT, $date60));
var_dump(date(C_DATE_FORMAT, $dateFirstMonday));


/**
 * http://wiki.yaslaw.info/wikka/PhpFindWeekdays
 * Sucht bestimmte Wochentage eines Monats aus
 * @param variant weekday
 * @param int month
 * @param int year
 * @return Array<TimeStamp>
 */
function findWeekdays($weekday, $month, $year) {
    $date = strtotime("next {$weekday}", mktime(0, 0, 0, $month, 1, $year));
    while(date('n', $date) == $month){
        $dates[] = $date;
        $date = strtotime("next {$weekday}", $date);
    }
    return $dates;
}
Einige Links aus meinem Wiki mit versch. Datzumsfunktionen
erweiterte PHP Datumsfunktionen

Nachtrag:
Das mit den 60 Tagen: siehe $date60 mit strtotime() in meinem Beispiel......
 
Das du Timestamps vermeiden willst, habe ich gelesen. Ich dachte allerdings das du die Datumsangaben nur nicht als solche speichern willst.

Welchen Nachteil du durch die Verwendung von strtotime hast, verstehe ich nicht.

Vielleicht hilft dir ja die DateTime::add Funktion weiter.
 
Hab noch herausgefunden, dass du mit strtotime('first monday of +0 month', $date) den ersten Montag des aktuellen Monats herausfinden kannst.

Mit DateTime würde das dann so aussehen
PHP:
define('C_DATE_FORMAT', 'd.m.Y');

//Datum setzen
$date = new DateTime('25.3.1912');
var_dump($date->format(C_DATE_FORMAT));

//60 Tage dazuzählen
$date->add(new DateInterval('P60D'));
var_dump($date->format(C_DATE_FORMAT));

//Ersten Samstag
$date->modify('first saturday of +0 month');
var_dump($date->format(C_DATE_FORMAT));

Ausgabe:
Code:
string(10) "25.03.1912"
string(10) "24.05.1912"
string(10) "04.05.1912"
 
Ich habs jetzt so Gelöst :
PHP:
//Überprüft ob das Jahr ein Schaltjahr ist
//Input: 2008
//Output: 1
function leap_year($Year)
{
    //wenn die Jahreszahl durch 4, aber nicht durch 100 teilbar ist. Sollte die Jahreszahl durch 400 teilbar sein, handelt es sich dennoch um ein Schaltjahr. 
    if (($Year % 400) == 0 || (($Year % 4) == 0 && ($Year % 100) != 0)) {
        return 1;
    } else {
        return 0;
    }
}

//Addiert/Subtrahiert $Days zu $Date
//Input: 17-1-2008
//           +10
//Output: 27-1-2008
function modify_date($Date,$Days = +0)
{
    //Zerlege $Date
    $output = @preg_split('/-/', $Date);
    //Tage der Monate
    $Month_Days = array(31,
                        28,
                        31,
                        30,
                        31,
                        30,
                        31,
                        31,
                        30,
                        31,
                        30,
                        31);
    
    $daynow = $output[0]+$Days;
    $monthnow = $output[1];
    $yearnow = $output[2];
    //Tage Addiern dann Datum Addiern ansonsten Subtrahieren
    if ($Days >= 0)
    {
        while($daynow > ($Month_Days[$monthnow-1]+leap_year($yearnow)))
        {
            $daynow = $daynow - ($Month_Days[$monthnow-1]+leap_year($yearnow));
            $monthnow = $monthnow + 1;
            if ($monthnow > 12)
            {
                $monthnow = 1;
                $yearnow = $yearnow + 1;
            }
        }
    }
    else
    {
        while($daynow <= 0)
        {
            $monthnow = $monthnow - 1;
            if ($monthnow <= 0)
            {
                $monthnow = 12;
                $yearnow = $yearnow - 1;
            }
            $daynow = ($Month_Days[$monthnow-1]+leap_year($yearnow)) + $daynow;
        }
    }
    return $daynow."-".$monthnow."-".$yearnow;
}

Außer das ich noch eine Abfrage machen muss, ob das Datum auch das richtige Format hatt, jemand noch verbesserungen daran?
 
Zuletzt bearbeitet:
Was soll dieses Script bewirken?
Erkläre mal was es macht oder schreib einige Komentarzeilen rein.

In der 2ten Funktion - in welchem Format erwartest du $Date? Muss ja irgend ein String sein wenn du mit preg_split() darüber gehst.

Und vor allem: warum verwendest du nicht die Funktionen die wir dir gezeigt habe? DateTime arbeitet auch vor 1970 -> schau mein Beispiel an.
 
Kommentare eingefügt, es soll Tage auf das Datum Addieren/Subtrahieren.

Ups die "1912" hab ich garnicht gesehen, und ich war der meinung gewesen das diese Funktionen mit Timestamps arbeiten...
nur die Frage bevor ich es damit versuche , sind das Funktionen die nur in PHP zur verfügung stehen oder auch in anderen zb.: Java?
 
Zurück