tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von saftmeister
ERLEDIGT
NEIN
ANTWORTEN
8
ZUGRIFFE
589
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von suntrop
    suntrop suntrop ist offline Mitglied Brokat
    Registriert seit
    Dec 2001
    Ort
    Köln
    Beiträge
    452
    Hallo PHPler

    Ich möchte den relativen Zeitversatz zum heutigen Tag ausgeben. Zum Beispiel: heute, gestern, morgen, am Sonntag, vor 12 Tagen, etc.

    Ich habe jetzt schon viele Möglichkeiten versucht. Rechnen mit dem timestamp und den vergangenen Sekunden geht nicht. Ist es aktuell 00:05 Uhr und mein Vergleichszeitpunkt ist 10 Minuten früher, dann will ich "gestern" ausgeben. Also kann ich nicht mit den verstrichenen Sekunden arbeiten.

    Mit einem DateTime-Objekt und diff() kann ich scheinbar auch nicht korrekt rechnen. Denn zum einen erhalte ich immer nur positive Werte (egal ob es vor 3 Tagen ist oder in 3 Tagen). Außerdem scheint diff() nicht in Tagen sondern auch in Zeitabständen zu rechnen. Gestern muss also mindestens 24 Stunden zurück liegen. Andernfalls ist es nicht gestern

    PHP-Code:
    $today = new DateTime();
    $yesterday = new DateTime('-1 day');
    $tomorrow = new DateTime('+1 day');
    $due = new DateTime($date);
            
    $span $due->diff($today)->days;
        
    if (
    $span == 0)
    {
        return 
    'heute';

    Ein Zeitpunkt vor 20 Stunden wird leider auch als "heute" ausgegeben.

    Was kann ich bei der Misere mache? Für heute, morgen, gestern kann ich noch einen direkten Datumsvergleich (Y-m-d) machen. Aber wie berechnen ich die tatsächlichen vergangenen Tage?

    Sorry, ich glaube ich habe mich etwas umständlich ausgedrückt
    Hoffe dennoch auf Unterstützung. Danke und Grüße.
     

  2. #2
    Milliongame Milliongame ist offline Mitglied Bronze
    Registriert seit
    Oct 2007
    Beiträge
    31
    Also wenn ich dich richtig verstanden habe, willst so etwas wie Zeitzonen simulieren? Du brauchst doch nur von deinem aktuellen Timestamp, den Versatz subtrahieren, schon hast du deine neue Zeit.

    PHP-Code:
    // Dein Timestamp
    $timestamp time();
    // Der Versatz
    $timeFactor 60 60 24;
    // Deine Zeit mit Versatz
    $localTime $timstamp $timeFactor;
    // Datumsformat
    $timeFormat DATE_COOKIE// siehe http://www.php.net/date
    // Zeit formatieren und ausgeben
    echo date($imeFormat$localTime); 
     

  3. #3
    Avatar von suntrop
    suntrop suntrop ist offline Mitglied Brokat
    Registriert seit
    Dec 2001
    Ort
    Köln
    Beiträge
    452
    Danke für deine Antwort. Die Zeitzone ist glaube ich bei der relative Zeitausgabe egal.
    "Vor 3 Tagen" bleibt "vor 3 Tagen", egal ob in Berlin oder New York.

    Mir geht es darum, dass ich nicht in ganzen Tagen rechnen kann.

    Angenommen jetzt ist: 2011-12-09 20:00:00

    Ich will den relativen Zeitversatz (Differenz in Tagen) zu folgenden Zeitpunkten:

    2011-12-08 16:00:00
    2011-12-08 22:00:00
    2011-12-24 10:00:00

    Würde ich jetzt die Differenz in Sekunden berechnen, dann liegt das zweite Datum nur 22 Stunden zurück. Also keinen ganzen Tag in Sekunden ausgedrückt. Dennoch ist es für jeden Mensch "gestern". Es lässt sich jedoch schwer oder nur umständlich berechnen.

    Ich denke ich habe eine Lösung gefunden. Ich ziehe die Differenz aus allen Tage zu dem gewünschten Datum um 0 Uhr. Dann gibt es keine Rundungsfehler

    Vielleicht hat ja jemand ein besseren Vorschlag.
    PHP-Code:
    function relative_date($date)
        {
            
    $due strtotime($date);
            
    $now time();
            
    setlocale (LC_ALL'de_DE');
            
            
    $today date('Y-m-d'$now);
            
    $yesterday strftime('%Y-%m-%d'strtotime('-1 day'$now));
            
    $tomorrow strftime('%Y-%m-%d'strtotime('+1 day'$now));
            
    //echo $tomorrow;
            
            
            // Today at 00:00:00 o'clock
            
    $today_day strftime('%d'time());
            
    $today_month strftime('%m'time());
            
    $today_year strftime('%Y'time());
            
    $pastdays mktime(000$today_month$today_day$today_year) / 86400;
            
            
    // The due date at 00:00:00 o'clock
            
    $due_day strftime('%d'$due);
            
    $due_month strftime('%m'$due);
            
    $due_year strftime('%Y'$due);
            
    $newdue mktime(000$due_month$due_day$due_year);
            
            
    $daydiff $pastdays - ($newdue 86400);
            
            
            if (
    strftime('%Y-%m-%d'$due) == $today)
            {
                return 
    'heute';
            }
            if (
    strftime('%Y-%m-%d'$due) == $yesterday)
            {
                return 
    'gestern';
            }
            if (
    strftime('%Y-%m-%d'$due) == $tomorrow)
            {
                return 
    'morgen';
            }
            
            
            
    // Due is in the past
            
    if ($due $now)
            {
                
    // Last 7 days
                
    if ($span 604800)
                {
                    return 
    'letzter ' strftime('%A'$due) . ' <span class="light">('$daydiff .' Tage überfällig)</span>';
                }
                else
                {
                    return 
    strftime('%d. %b'$due) . ' <span class="light">('floor($span/86400) .' Tage überfällig)</span>';
                }
            }
            else 
    // Due is in the future
            
    {
                
    $span $span * -1;
                
                if (
    $span 604800)
                {
                    return 
    strftime('%A'$due);
                }
                else
                {
                    return 
    strftime('%d. %b'$due) . ' <span class="light">(' strftime('%V'$due) . '. KW, in 'floor($span/86400) .' Tage)</span>';
                }
            }

            return 
    $date;
        } 
     

  4. #4
    Avatar von saftmeister
    saftmeister saftmeister ist offline Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Genauso muss man es machen, es gibt keine andere Lösung, vielleicht einen generalisierten Ansatz. Ist die DateTime-Klasse die aus der SPL (also PHP-Standard)? Dann habe ich eine schönere Lösung für dich:

    Code php:
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    
    <?php
    ini_set('display_errors', 1);
    error_reporting(E_ALL|E_STRICT);
    date_default_timezone_set('Europe/Berlin');
     
    class CustomDateTime extends DateTime
    {
        /**
         * This function calculates the due of days to now from an specific date 
         * 
         * @param DateTime $fromDate The date to calculate the days
         */
        public function dueDays(DateTime $fromDate)
        {
            // Get the current time stamp       
            $nowTimestamp = $this->getTimestamp();
            // Get the time stamp of the date and time to calculate the due days
            $fromDateTimestamp = $fromDate->getTimestamp();
            
            // Get the first hour of the date now
            $todayZero = $nowTimestamp - ($nowTimestamp % 86400);
            // Get the first hour of the date to calculate the due days
            $fromDayZero = $fromDateTimestamp - ($fromDateTimestamp % 86400);
            
            // Calculate the difference in days
            $diffDays = ($todayZero - $fromDayZero) / 86400;
            
            return abs($diffDays);
        }
    }
     
    $now = new CustomDateTime();
    $yesterday = new CustomDateTime('-1day');
    $specificDate = new CustomDateTime('2011-12-06 17:30');
    $tomorrow = new CustomDateTime('+1day');
    $nextWeek = new CustomDateTime('+1week');
     
    echo $now->dueDays($yesterday) . "<br/><br/>";
    echo $now->dueDays($specificDate) . "<br/><br/>";
    echo $now->dueDays($tomorrow) . "<br/><br/>";
    echo $now->dueDays($nextWeek) . "<br/><br/>";

    EDIT: Habe den Code noch mal angepasst, es werden jetzt absolute Werte zurück gegeben, da man sonst bei "tomorrow" eine -1 zurück bekommt.
    Geändert von saftmeister (10.12.11 um 10:50 Uhr)
    suntrop bedankt sich. 
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  5. #5
    kourty kourty ist offline Mitglied Bronze
    Registriert seit
    Apr 2011
    Beiträge
    40
    Ich hatte mal ein ähnliches Problem, hab das aber so gelöst, dass ich mit mktime() den Timestamp um 0:00 brerechnet habe und dann geguckt, ob ein timestamp dazwischen liegt. Zum Beispiel so:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    
    <?php
    $gestern = (mktime(0,0,0,date("m",time()),date("d",time()),date("Y",time()))  - 86400);
    $heute = mktime(0,0,0,date("m",time()),date("d",time()),date("Y",time()));
     
    if ($timestamp > $gestern AND $timestamp < $heute)
        echo "Gestern";
     
    ?>

    Ist zwar recht umständlich, aber übersichtilich wie ich finde.
     

  6. #6
    Avatar von suntrop
    suntrop suntrop ist offline Mitglied Brokat
    Registriert seit
    Dec 2001
    Ort
    Köln
    Beiträge
    452
    Danke euch beiden für die Antworten.
    Die CustomDateTime-Klasse sieht gut aus. Etwas übersichtlicher als mein Konstrukt Werde das wohl etwas angepasst übernehmen. Danke dafür!

    @kourty
    Dein Ansatz ist etwas ähnlich zu meinem. Übersichtlich ist es Auch dir besten Dank für den Code!

    Grüße
    suntrop
     

  7. #7
    Avatar von saftmeister
    saftmeister saftmeister ist offline Der Saft sei mit dir
    tutorials.de Premium-User
    Registriert seit
    May 2006
    Ort
    There is no place like 127.0.0.1
    Beiträge
    3.521
    Wenn du eine zusätzliche Methode implementierst, kannst du auch prüfen, ob ein Datum älter ist als das andere:

    Code php:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
      /**
       * Checks whether the current date is earlier than the given date as parameter
       *
       * @param DateTime $checkDate The date to check against the current
       * @return boolean true if the current date is earlier, false if not
       */
      public function isEarlierThan(DateTime $checkDate)
      {
        return ($this->getTimestamp() < $checkDate->getTimestamp()) ? true : false;
      }

    Im Anhang findest du die CustomDateTime-Klasse mit PHPUnit-Test.
    Angehängte Dateien Angehängte Dateien
     
    Grüße
    --
    Qualität des Codes wird in WTF's/Min gemessen: Je mehr, desto schlechter der Code ;-)

  8. #8
    Avatar von hela
    hela hela ist offline Mitglied Smaragd
    tutorials.de Premium-User
    Registriert seit
    Oct 2004
    Beiträge
    1.123
    Hallo,
    so würde es auch funktionieren:
    PHP-Code:
    <?php

    $timeStamp 
    strtotime('2011-12-24 10:00:00');
    $span unixtojd($timeStamp) - unixtojd();

    switch (
    $span) {
        case -
    1:
            
    $msg 'gestern';
            break;
        case 
    0:
            
    $msg 'heute';
            break;
        case 
    1:
            
    $msg 'morgen';
            break;
        case (
    $span < -1):
            
    $msg 'vor '.$span*(-1).' Tagen';
            break;
        default:
            
    $msg 'in '.$span.' Tagen';        
    }

    echo 
    $msg;

    ?>
     

  9. #9
    Avatar von suntrop
    suntrop suntrop ist offline Mitglied Brokat
    Registriert seit
    Dec 2001
    Ort
    Köln
    Beiträge
    452
    Viele Wege führen nach Rom
    Die Funktion unixtojd() kannte ich nicht, aber damit ist es ja wirklich simpel eine Tagesdifferenz zu berechnen. Danke für den Tipp!
     

Ähnliche Themen

  1. Automatisches Update nach X Tagen
    Von Brölio im Forum PHP
    Antworten: 4
    Letzter Beitrag: 15.02.08, 16:50
  2. Einträge nach 30 Tagen löschen
    Von funnyzocker im Forum Relationale Datenbanksysteme
    Antworten: 3
    Letzter Beitrag: 07.04.07, 17:27
  3. Einträge nach 30 Tagen löschen
    Von funnyzocker im Forum PHP
    Antworten: 3
    Letzter Beitrag: 07.04.07, 17:27
  4. Outlook-Kalender-Einträge nach X-Tagen verschieben
    Von Hawkster im Forum Office-Anwendungen
    Antworten: 1
    Letzter Beitrag: 08.09.06, 08:21
  5. Tebelle automatisch nach X Tagen löschen
    Von Blattspinat im Forum Relationale Datenbanksysteme
    Antworten: 3
    Letzter Beitrag: 22.11.04, 22:12

Stichworte