Matthias Apsel: strtotime() letzter August gesucht

Hallo alle,

Ich suche den zurückliegenden 1. August als Beginn des aktuellen Schuljahres.

Also
heute = 3.1.2016 soll den 1.8.2015 liefern
heute = 3.9.2016 soll den 1.8.2016 liefern

Ein naives …

date('Y-m-d',strtotime('first day of August ago'))

… liefert aber den 1. August des aktuellen Jahres (Spielwiese)

Gibts da was ähnlich kurzes oder muss ich tatsächlich per Hand schauen, ob ich das aktuelle oder zurückliegende Jahr nehmen muss?

Bis demnächst
Matthias

--
Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)

akzeptierte Antworten

  1. Lieber Matthias,

    (Spielwiese)

    echo date('Y-m-d', strtotime('first day of August last year'));
    

    Liebe Grüße,

    Felix Riesterer.

    1. Hallo Felix Riesterer,

      echo date('Y-m-d', strtotime('first day of August last year'));
      

      Das liefert aber auch im September 2016 den 1. August 2015.

      Bis demnächst
      Matthias

      --
      Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
      1. Lieber Matthias,

        Das liefert aber auch im September 2016 den 1. August 2015.

        da finde ich im Manual leider auch nichts out-of-the-box. Du wirst wohl das Jahr abgleichen müssen...

        Liebe Grüße,

        Felix Riesterer.

    2. Hallo Felix,

      (Spielwiese)

      echo date('Y-m-d', strtotime('first day of August last year'));
      

      Das ist nicht das gesuchte. Gesucht wird der letzte August. Wenn er in diesem Jahr lag, dann dieses Jahr, ansonsten letztes Jahr.

      Ich glaube nicht, dass strtotime() das kann; ich habs zumindest nicht hinbekommen. Ich denke, dass muss man „zu Fuss“ machen. Wobei sich das ja auf eine einfache Fall-Unterscheidung beschränkt:

      echo date('Y-m-d', strtotime('first day of August' . (date('m') < 8 ? ' last year' : ''))), "\n";
      

      LG,
      CK

      1. Hallo Christian Kruse,

        Ich glaube nicht, dass strtotime() das kann; ich habs zumindest nicht hinbekommen. Ich denke, dass muss man „zu Fuss“ machen. Wobei sich das ja auf eine einfache Fall-Unterscheidung beschränkt:

        echo date('Y-m-d', strtotime('first day of August' . (date('m') < 8 ? ' last year' : ''))), "\n";
        

        Danke, auf das einfache Anhängen wäre ich so wohl auch nicht gekommen.

        Cool wäre date('Y-m-d', strtotime('first day of last August')), aber das führt auch bei der aktuellsten PHP-Version zum 31.12.1969.

        Bis demnächst
        Matthias

        --
        Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
  2. Moin!

    Sowas?

    <?php
    #Test:
    echo firstDayOfMounthAgo(1, '2016-01-11'), "\n";
    echo firstDayOfMounthAgo(1), "\n";
    echo firstDayOfMounthAgo(1, '2016-02-13'), "\n";
    echo firstDayOfMounthAgo(1, '1970-02-13'), "\n";
    
    
    function firstDayOfMounthAgo ($mounth, $date=false) {
      if (false === $date) $date=date('Y-m-d');
      list($Y, $M, $dummy) = explode('-', $date, 3);
      if ($M <= $mounth)    $Y--;
      return ("$Y-$mounth-1");
    }
    

    Ergebnisse:

    2015-1-1
    2015-1-1
    2016-1-1
    1970-1-1
    

    Weitere Umformungen kannst Du selbst ...

    Jörg Reinholz

    1. Hallo,

      $mounth

      Müssen unter Linux auch Monate erst gemountet werden?

      SCNR

      Gruß
      Kalk

      1. Moin!

        Müssen unter Linux auch Monate erst gemountet werden?

        Aber klar doch!

        Das Umformen:

        return date("Y-m-d", strtotime("$Y-$mounth-1"));
        

        Also kann man auch:

        <?php
        #Test:
        echo firstDayOfMounthAgo(1, '2016-01-11'), "\n";
        echo firstDayOfMounthAgo(1), "\n";
        echo firstDayOfMounthAgo(1, '2016-02-13'), "\n";
        echo firstDayOfMounthAgo(1, '1970-02-13'), "\n";
        
        
        function firstDayOfMounthAgo ($mounth, $format='Y-m-d', $date=false) {
          if (false === $date) $date=date('Y-m-d');
          list($Y, $M, $dummy) = explode('-', $date, 3);
          if ($M <= $mounth)    $Y--;
          return date($format, strtotime("$Y-$mounth-1"));
        }
        

        Jörg Reinholz

        1. Moin!

          Da habe ich aber gewaltig was falsch gemacht und auch die Reihenfolge der Parameter ist zu optimieren:

          <?php
          #Test:
          echo firstDayOfMounthAgo ( 1, '2016-01-11', 'Y-m-d' ), "\n";
          echo firstDayOfMounthAgo ( 1 ), "\n";
          echo firstDayOfMounthAgo ( 1, '2016-02-13', 'Y-m-d' ), "\n";
          echo firstDayOfMounthAgo ( 1, '1969-02-13', 'Y-m-d' ), "\n";
          
          function firstDayOfMounthAgo ( $mounth, $date = false, $format = 'Y-m-d' ) {
            if ( false === $date ) $date = date( 'Y-m-d' );
            list( $Y, $M, $dummy ) = explode( '-', $date, 3 );
            if ( $M <= $mounth )    $Y--;
            return date( $format, mktime( 0, 0, 0, $mounth, 1, $Y ) );
          }
          

          Resultate:

          2015-01-01
          2015-01-01
          2016-01-01
          1969-01-01
          

          Jörg Reinholz

    2. Lieber Jörg,

      was ist ein mounth? Meintest Du das englische Wort für Monat?

      Liebe Grüße,

      Felix Riesterer.

      1. Moin!

        Liebe Grüße,

        Du bist nur Zweiter!

        Jörg Reinholz

  3. Nimm den julian. Tag des 1.8. vom aktuellen Jahr. Wenn dieser Tag größer ist als der julian. Tag des aktuellen Datums, dann fällt der gesuchte 1.8. in das Jahr vorher. Ansonsten in das aktuelle Jahr.

    1. Tach,

      Nimm den julian. Tag des 1.8. vom aktuellen Jahr. Wenn dieser Tag größer ist als der julian. Tag des aktuellen Datums, dann fällt der gesuchte 1.8. in das Jahr vorher. Ansonsten in das aktuelle Jahr.

      wo läge der Vorteil, den Timestamp nochmal in ein anderes Format umzurechnen?

      mfg
      Woodfighter

      1. Was fürn Timestamp? Für die Aufgabenstellung sind Jahr und Tag relevant. Und zur Lösung ist nur eine Tagesdifferenz zu berechnen.

        1. Hallo pl,

          Was fürn Timestamp? Für die Aufgabenstellung sind Jahr und Tag relevant. Und zur Lösung ist nur eine Tagesdifferenz zu berechnen.

          Christians Lösung ist

          • kurz
          • menschenlesbar
          • zielführend

          Dein und auch Jörgs Vorschlag erlauben eine Verallgemeinerung, die in diesem Fall nicht benötigt wird. Aber ja: Ich stimme zu, deine Lösung wäre ebenfalls richtig und die Verwendung des Timestamps wäre nicht hilfreich.

          Bis demnächst
          Matthias

          --
          Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
        2. Tach,

          Was fürn Timestamp?

          erinnere ich mich falsch, dass aus strtotime ein Unix-Timestamp rauskommt?

          Für die Aufgabenstellung sind Jahr und Tag relevant. Und zur Lösung ist nur eine Tagesdifferenz zu berechnen.

          Deswegen frage ich ja, wo der Vorteil des Julianischen Datums gegenüber einem Unix-Timestamp wäre.

          mfg
          Woodfighter

          1. Hallo woodfighter,

            Deswegen frage ich ja, wo der Vorteil des Julianischen Datums gegenüber einem Unix-Timestamp wäre.

            Aus der Timestampdifferenz kann man nicht erkennen, ob ein Jahreswechsel dazwischen liegt (Schaltjahr).

            Bis demnächst
            Matthias

            --
            Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
            1. Hallo woodfighter,

              Deswegen frage ich ja, wo der Vorteil des Julianischen Datums gegenüber einem Unix-Timestamp wäre.

              Aus der Timestampdifferenz kann man nicht erkennen, ob ein Jahreswechsel dazwischen liegt (Schaltjahr).

              Natürlich kannst Du, anstatt eine Tagesdifferenzn zu berechnen, auch eine Sekundendifferenz zum Vergleich heranziehen. Ob in der Differenz ein Jahreswechsel liegt ist völlig uninteressant.

            2. Tach,

              Deswegen frage ich ja, wo der Vorteil des Julianischen Datums gegenüber einem Unix-Timestamp wäre.

              Aus der Timestampdifferenz kann man nicht erkennen, ob ein Jahreswechsel dazwischen liegt (Schaltjahr).

              das wollte ich auch nicht behaupten, aber den Timestamp könnte man in die Datumsfunktionen von PHP werfen (wie Christian es in seiner Lösung getan hat) oder direkt vergleichen (s.u.), wohingegen man fürs Julianische Datum erstmal eine passende Klasse finden und einbinden müsste.

              echo date('Y-m-d', strtotime('today') < strtotime('first day of August this year') ? strtotime('first day of August last year') : strtotime('first day of August this year'));
              

              mfg
              Woodfighter

              1. Hallo woodfighter,

                das wollte ich auch nicht behaupten, aber den Timestamp könnte man in die Datumsfunktionen von PHP werfen (wie Christian es in seiner Lösung getan hat) oder direkt vergleichen (s.u.), wohingegen man fürs Julianische Datum erstmal eine passende Klasse finden und einbinden müsste.

                echo date('Y-m-d', strtotime('today') < strtotime('first day of August this year') ? strtotime('first day of August last year') : strtotime('first day of August this year'));
                

                Naja, es gibt cal_to_jd. Und das würde tatsächlich erlauben, den letzten [beliebiges Datum] zu suchen. Und ohne sollte es auch klappen.

                $wunschdatum = '23 September';
                echo date('Y-m-d', strtotime('today') < strtotime($wunschdatum . ' this year') ? strtotime($wunschdatum . ' last year') : strtotime($wunschdatum . ' this year'));
                

                ungetestet. Aber wie gesagt, geht an der Aufgabenstellung vorbei, wäre eine Verallgemeinerung, die in meinem Fall nicht motwendig ist.

                Bis demnächst
                Matthias

                --
                Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
                1. Hallo Matthias,

                  Aber wie gesagt, geht an der Aufgabenstellung vorbei, wäre eine Verallgemeinerung, die in meinem Fall nicht motwendig ist.

                  Naja, im Sinne von „there is no temporary solution” sollte man sowas immer verallgemeinern ;-)

                  LG,
                  CK

                  1. Hallo Christian Kruse,

                    Naja, im Sinne von „there is no temporary solution” sollte man sowas immer verallgemeinern ;-)

                    Am besten als PullRequest bei strtotime ;-)

                    Bis demnächst
                    Matthias

                    --
                    Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
                    1. Hallo Matthias,

                      Naja, im Sinne von „there is no temporary solution” sollte man sowas immer verallgemeinern ;-)

                      Am besten als PullRequest bei strtotime ;-)

                      Ein ambitioniertes, aber unterstützenswertes Projekt – gogo, du schaffst das! ;-)

                      LG,
                      CK

              2. Hallo woodfighter,

                Deswegen frage ich ja, wo der Vorteil des Julianischen Datums gegenüber einem Unix-Timestamp wäre.

                Aus der Timestampdifferenz kann man nicht erkennen, ob ein Jahreswechsel dazwischen liegt (Schaltjahr).

                das wollte ich auch nicht behaupten, aber den Timestamp könnte man in die Datumsfunktionen von PHP werfen (wie Christian es in seiner Lösung getan hat) oder direkt vergleichen (s.u.), wohingegen man fürs Julianische Datum erstmal eine passende Klasse finden und einbinden müsste.

                Ich habe date('m') gewählt weil das idiomatischer ist. date('m') < 8 versteht man sofort, über strtotime('today') < strtotime('first day of August this year') muss man erst nachdenken was damit bezweckt wird.

                Abgesehen davon halte ich strtotime('today') sowie die Wiederholung von strtotime('first day of August this year') für suboptimal ;-)

                Ich denke allerdings, dass eine Misch-Lösung tatsächlich am besten lesbar wäre:

                <?php
                $now = time();
                $august_this_year = strtotime('first day of August this year', $now);
                $august_last_year = strtotime('first day of August last year', $now);
                
                echo date('Y-m-d', $now < $august_this_year ? $august_last_year : $august_this_year);
                

                Das Verpacken in Variablen ist nicht nur der Lesbarkeit geschuldet, sondern dient auch als Cache.

                LG,
                CK

                1. Tach,

                  Ich habe date('m') gewählt weil das idiomatischer ist. date('m') < 8 versteht man sofort, über strtotime('today') < strtotime('first day of August this year') muss man erst nachdenken was damit bezweckt wird.

                  Abgesehen davon halte ich strtotime('today') sowie die Wiederholung von strtotime('first day of August this year') für suboptimal ;-)

                  definitiv, deine Lösung war schöner; mir ging's ja nur darum, dass Julianische Datum als sinnvolle Lösung in diesem Falle (sinnvolle Anwendungszwecke für dieses fallen mir nur ein, wenn der Wertebereich des Unix-Timestamps zu klein ist (64 bit to the rescue)) zu entkräften.

                  Ich denke allerdings, dass eine Misch-Lösung tatsächlich am besten lesbar wäre:

                  <?php
                  $now = time();
                  $august_this_year = strtotime('first day of August this year', $now);
                  $august_last_year = strtotime('first day of August last year', $now);
                  
                  echo date('Y-m-d', $now < $august_this_year ? $august_last_year : $august_this_year);
                  

                  Das Verpacken in Variablen ist nicht nur der Lesbarkeit geschuldet, sondern dient auch als Cache.

                  Ja, aber dann ist es doch kein Einzeiler mehr, der Rouge verwirrt ;-)

                  mfg
                  Woodfighter

              3. Da eigentliche Problem ist die Formulierung der Aufgabenstellung nämlich so, dass sie programmiertechnisch umgesetzt werden kann:

                Im Gleichen Jahr: Liegt der 1.8. Vor oder Hinter Meinem Datum?

                Wenn er Dahinter liegt, ist es das Jahr vorher.

                Das ist genauso verständlich wie einfach und kann auch über BuiltIn-Funktionen gerechnet werden.pl