Zum Inhalt springen

in PHP nach Datum sortieren


Empfohlene Beiträge

Benutze eine benutzerdefinierte Sortierfunktion. Ich hab hier mal eine hingestellt:

<?php

function datum_vergleich($a, $ {
if ($a == $ return 0;
$aa = explode(".",$a);
$bb = explode(".",$;

if ($aa[2] > $bb[2])
return 1;
elseif ($aa[2] < $bb[2])
return -1;
elseif ($aa[1] > $bb[1])
return 1;
elseif ($aa[1] < $bb[1])
return -1;
elseif ($aa[0] > $bb[0])
return 1;
else
return -1;
}

$daten = array(
"11.06.2000",
"01.01.1492",
"10.05.2000",
"10.06.2000",
"12.05.2000");

usort($daten,"datum_vergleich");

print_r($daten);

?>[/PHP]

Hoffe, es hilft dir was :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

ich hab jetzt selber was gebastelt. Einen Bubblesort. Funktioniert aber nicht so richtig.

Als Dreieckstausch hab ich


$platzhalter = $alles[$var1];
$alles[$var1] = $alles[$var2];
$alles[$var2] = $platzhalter;

[/PHP]

$alles ist ein 2d. Array

$platzhalter wird hier zum 1. mal erwähnt und war vorher nicht verwendet

Kann das funktionieren oder ist es eine andere Fehlerquelle?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mit RegEx noch etwas kürzer:


function sortdate($a,$
{
$pattern='/(\d.*?).(\d.*?).(\d.*?)$/';
$replace='$3-$2-$1';
$ta = strtotime(preg_replace($pattern,$replace,$a));
$tb = strtotime(preg_replace($pattern,$replace,$);
return $ta>$tb;
}


$datum = array(
"13.08.1997","16.12.1977","25.08.1979","05.05.2004"
);

usort($datum,"sortdate");

print_r($datum);
[/PHP]

Link zu diesem Kommentar
Auf anderen Seiten teilen

also tut mir leid, aber eure codes versteh ich nicht ganz. Bin noch nicht so fit in php.



for($var1=0;$var1<=$count;$var1++)
{
for($var2=0;$var2<=$count;$var2++)
{
//Datum zerlegen:
//Datum von ersteren Datensatz zerlegen:
$datumpunkt1 = strpos($alles[$var1][0],".",0);
$datumpunkt2 = strpos($alles[$var1][0],".",$datumpunkt1+1);

$tt = substr($alles[$var1][0],0,$datumpunkt1);
$mm = substr($alles[$var1][0],$datumpunkt1+1,$datumpunkt2-$datumpunkt1-1);
$jjjj = substr($alles[$var1][0],$datumpunkt2+1,4);

//Datum von nächsten Datensatz zerlegen:
$datumpunkt1 = strpos($alles[$var2][0],".",0);
$datumpunkt2 = strpos($alles[$var2][0],".",$datumpunkt1+1);

$tt2 = substr($alles[$var2][0],0,$datumpunkt1);
$mm2 = substr($alles[$var2][0],$datumpunkt1+1,$datumpunkt2-$datumpunkt1-1);
$jjjj2 = substr($alles[$var2][0],$datumpunkt2+1,4);


settype($tt,"integer");
settype($mm,"integer");
settype($jjjj,"integer");
settype($tt2,"integer");
settype($mm2,"integer");
settype($jjjj2,"integer");

//IF Abfrage zum Herausfinden was größer ist
if($jjjj2 <= $jjjj)
if($mm2 <= $mm)
if($tt2 < $tt)
{
//Dreieckstausch
$platzhalter = $alles[$var1];
$alles[$var1] = $alles[$var2];
$alles[$var2] = $platzhalter;
}

}
}

[/PHP]

das ist mein code. Dass das mit dem Zerlegen funktioniert glaub ich ziemlich sicher. Irgendwo anders ist der Hund begraben.

Ach ja im Array $alles[irgendeinezahl][0] steht die "0" für das Datum im format TT.MM.JJJJ

Link zu diesem Kommentar
Auf anderen Seiten teilen

@computercrustie: hast recht .. hab ich gar net dran gedacht. Aber der arme Brei verzweifelt dann noch mehr :)

@Brei: zum Zerlegen schau dir die Funktion explode mal an. Kann man oft gebrauchen!

was kommt denn bei dir raus? BTW: print_r($variable) ist eine sehr schöne Anweisung, um Arrays,Objekte etc. auszugeben. Zum debuggen wunderschön *gg

Link zu diesem Kommentar
Auf anderen Seiten teilen

JETZT weiss ich, worauf du hinauswillst!

Also nochmal


function sort_by_date($a,$
{
$pattern='/(\d.*?).(\d.*?).(\d.*?)$/';
$replace='$3-$2-$1';
$ta = strtotime(preg_replace($pattern,$replace,$a[0]));
$tb = strtotime(preg_replace($pattern,$replace,$b[0]));
return $ta>$tb;
}


usort($alles,"sort_by_date");

print_r($alles);
[/PHP]

Nimm deine Bubblesort-Funktion raus, integriere die "sort_by_date"-Funktion (s.o.) und sortiere dann mittels usort dein Array.

Ich habe den Aufruf hier gleich so gemacht, dass er auf dein Beispiel passt (Datensatzarray heißt $alles und $alles[..][0] ist immer das Datum).

Zur Funktionsweise:

mittels usort(..) kannst du ein Array (1. Parameter) über eine benutzerdefinierte Funktion (2. Parameter, Funktionsname als String) sortieren. Hierbei werden der benutzerdefinierten Funktion zwei Parameter (zwei zu vergleichende Elemente des zu sortierenden Arrays) übergeben, mit denen du dann deinen Vergleich machen kannst.

In deinem konkreten Fall sind diese zwei Elemente auch wiederum Arrays, so dass wir uns aus diesen das entsprechende Feld (hier Index 0) nehmen müssen, um einen Vergleich anstellen zu können.

Ich habe hier mit RegEx nichts weiter getan, als das Datum vom Format dd.mm.yyyy in eine für strtotime(..) verständliche (englische) Notation zu bringen (yyyy-mm-dd). strtotime(..) wandelt jetzt dieses Datum in einen Unix-Timestamp (Anzahl Sekunden seit 1.1.1970) um, so dass diese sich jetzt vergleichen lassen.

Soll das Array absteigend sortiert werden, musst du lediglich

$ta>$tb durch $tb>$ta ersetzen.

Ich hoffe, das hat geholfen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Bubblesort müsste übrigens richtiger so aussehen:


function bubble_sort($alles)
{
$pattern='/(\d.*?).(\d.*?).(\d.*?)$/';
$replace='$3-$2-$1';
do
{
$ok = true;
for ($i=0; $i < (count($alles)-1); $i++)
{
$ta = strtotime(preg_replace($pattern,$replace,$alles[$i][0]));
$tb = strtotime(preg_replace($pattern,$replace,$alles[$i+1][0]));
if ($ta>$tb)
{
$tmp = $alles[$i];
$array[$i] = $alles[$i+1];
$alles[$i+1] = $tmp;
$ok = false;
}
}
} while (!$ok);
}
[/PHP]

Ich habe deine Datumzerlegung mal ersetzt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

aha, danke. Dein sort_by_date funktioniert.

Aber jetzt möchte ich das ganze halt noch verstehen.

Was ist jetzt bei meinem bubblesort falsch?

Eigentlich nur der Vergleich:


if($jjjj2 <= $jjjj)
if($mm2 <= $mm)
if($tt2 < $tt)
{...}
[/PHP]

Angenommen, Datum 2 ist 10.12.2001 und Datum 1 der 10.10.2004:

[PHP]
if ( 2001 <= 2004 )
//ja, also
if (12 <= 10)
//nein, also abbruch, obwohl Datum2 kleiner Datum1 ist!

Dein Algorithmus ist auch sehr verschwenderisch, da die Iteration komplett durchlaufen wird, auch wenn bereits alle Werte sortiert sind.

Das ist eine gute Frage von Jaraz...

Holst du die Daten eventuell aus einer Datenbank ?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die Daten kommen aus einer Textdatei mit dem Aufbau:

Datum;Beschreibung;Beschreibung;Datensatznr

Dann würde ich beim einlesen jeweils den entsprechenden Timestamp mit mktime bilden und danach sortieren.

Die geposteten Sortierverfahren mögen funktionieren. Was schneller ist, müßte man messen. Ich finde das timestamp bilden allerdings flexibler im Bezug auf mögliche verschiedene Datumsformate.

Gruß Jaraz

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die Daten kommen aus einer Textdatei mit dem Aufbau:

Datum;Beschreibung;Beschreibung;Datensatznr

Hast du denn keine Möglichkeit, eine Datenbank für diese Zwecke zu nutzen ?

Damit wärst du wesentlich schneller und hast auch viel mehr (zumindest einfachere) Möglichkeiten zur Bearbeitung der Datensätze.

Zu dem Hinweis von Jaraz:

Solltest du keine Datenbank nutzen können, dann nimm auf jeden Fall einen Unix-Timestamp, denn damit sparst du dir auch das Konvertieren beim Sortieren und somit auch Rechenzeit.

@Jaraz:

Da mittels usort() kein Interpreter-Code ausgeführt werden muss (ausser zum Vergleich), denke ich, dass diese Variante nach dem Einlesen die schnellere ist. Denn da es keine "Insert"-Funktion für Arrays in PHP gibt (zumindest noch nicht) müssten ja die Element beim "Davor"-Einfügen immer um eins nach hinten verschoben werden (wenn man nicht zwei Arrays nutzt).

Und was auch wichtig wäre ist die Anzahl der Datensätze.

Auf jeden Fall eine interessante Frage.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also nochmal zum Verständnis:

$ta = strtotime(preg_replace($pattern,$replace,$alles[$i][0]));

strtotime macht aus einem Datum eine schöne Zahl, die man gut vergleichen kann. Damit das funktioniert muss das Datum ein bestimmtes format haben. Das wird mit preg_replace gemacht. Dieser Befehl ist mir nicht ganz klar.

Link zu diesem Kommentar
Auf anderen Seiten teilen

preg_replace($pattern,$replace,$text) führt eine Ersetzung in $text von einem regulären Ausdruck $pattern durch $replace aus.

In unserem Fall liegt das Datum als tt.mm.yyyy vor, wobei die drei Bestandteile durch Punkte getrennt sind.

Demzufolge muss der reguläre Ausdruck so aussehen:


/(\d.*?).(\d.*?).(\d.*?)$/

(\d.*?). findet eine Zahlen bis zum Punkt und erzeugt eine sogenannte Backreference (dadurch können wir uns beim Ersetzen in $replace darauf beziehen)

(\d.*?).(\d.*?). findet zwei Zahlen (jeweils eine Backreference) durch Punkt getrennt wobei die zweite am Ende einen Punkt haben muss.

.(\d.*?)$ findet eine Zahl vor der ein Punkt vorkommt und die am Ende des $text steht

in $replace können wir uns nun auf diese Backreferences beziehen. Diese werden in der Reihenfolge des Auftretens in $pattern durchnummeriert (beginnend bei 1).

Das erfolgt durch

$3-$2-$1

Hier wird das zerlegte Datum in der Form yyyy-mm-tt wieder zusammengesetzt...

...und ist somit für strtotime(...) interpretierbar.

Wenn du aber, wie Jaraz bereits geschrieben hast, das Datum in deinen Datensätzen gleich als Timestamp (Sekunden seit 01.01.1970) ablegst, dann ist diese Umwandlung nicht mehr notwendig und ausgeben kannst du das Datum dann via date("d.m.Y",$timestamp)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...