Brei Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 Hallo ich habe in einem array datensätze wobei darunter auch einmal Datumsinformationen vorkommen. Wie kann ich nun alle Datensätze nach dem Datum sortieren? Gibts da ne Funktion? Datumsformat wäre TT.MM.JJJJ Zitieren
etreu Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 In deinem Fall sollte dir die Funktion array_multisort weiterhelfen. Wenn nicht, dann kannst du dir noch eine eigene Sortierfunktion schreiben und diese dann mit array_walk anwenden. Zitieren
kLeiner_HobBes Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 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 Zitieren
Brei Geschrieben 16. Juni 2004 Autor Geschrieben 16. Juni 2004 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? Zitieren
computercrustie Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 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] Zitieren
Brei Geschrieben 16. Juni 2004 Autor Geschrieben 16. Juni 2004 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 Zitieren
kLeiner_HobBes Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 @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 Zitieren
Brei Geschrieben 16. Juni 2004 Autor Geschrieben 16. Juni 2004 Was bei mir rauskommt? Es wird schon irgendwie die Reihenfolge geändert. Aber nicht wie ich möchte. Es verändert halt die Reihenfolge, aber es ist nicht sortiert. Was bringt mir print_r($variable)? Zitieren
computercrustie Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 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. Zitieren
computercrustie Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 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. Zitieren
Brei Geschrieben 16. Juni 2004 Autor Geschrieben 16. Juni 2004 aha, danke. Dein sort_by_date funktioniert. Aber jetzt möchte ich das ganze halt noch verstehen. Was ist jetzt bei meinem bubblesort falsch? Zitieren
Jaraz Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 Hi, wo kommen die Daten denn her? Gruß Jaraz Zitieren
computercrustie Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 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 ? Zitieren
kills Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 Hi, wo kommen die Daten denn her? Gruß Jaraz das würde mich auch interessieren. wenn du die daten aus einer db bekommst könntest du das ganze ganz easy per "order by" im SQL bei der abfrage schon vorsortieren! Zitieren
Brei Geschrieben 16. Juni 2004 Autor Geschrieben 16. Juni 2004 Die Daten kommen aus einer Textdatei mit dem Aufbau: Datum;Beschreibung;Beschreibung;Datensatznr Zitieren
Jaraz Geschrieben 16. Juni 2004 Geschrieben 16. Juni 2004 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 Zitieren
computercrustie Geschrieben 17. Juni 2004 Geschrieben 17. Juni 2004 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. Zitieren
Brei Geschrieben 17. Juni 2004 Autor Geschrieben 17. Juni 2004 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. Zitieren
computercrustie Geschrieben 17. Juni 2004 Geschrieben 17. Juni 2004 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) Zitieren
Brei Geschrieben 17. Juni 2004 Autor Geschrieben 17. Juni 2004 Hast du zufällig einen link für dieses preg_replace? Die ganzen Zeichenketten sehen ganz schön kryptisch für mich aus. Die Zuordnung bräuchte ich da fast zum verstehen Zitieren
kLeiner_HobBes Geschrieben 17. Juni 2004 Geschrieben 17. Juni 2004 Bauelemente einer Regex: http://www.dclp-faq.de/q/q-regexp-bauelemente.html Regex ansich: http://www.dclp-faq.de/ch/ch-regexp.html Zitieren
computercrustie Geschrieben 18. Juni 2004 Geschrieben 18. Juni 2004 Aber gern doch: RegEx-Tutorial (für preg-Funktionen) Zitieren
Brei Geschrieben 23. Juni 2004 Autor Geschrieben 23. Juni 2004 Jetzt ist mir augefallen dass bei einem Datum irgendwann ab dem Jahr 2038 die Sortierung falsch läuft. Wie kann das sein? Gibts da eine Einschränkung beim timestamp? Zitieren
kills Geschrieben 23. Juni 2004 Geschrieben 23. Juni 2004 kannst du mal nen auschnitt der ausgabe posten und den code den du nun verwendest Zitieren
forTeesSake Geschrieben 23. Juni 2004 Geschrieben 23. Juni 2004 ja, scheint 2038 zu enden und nennt sich "ende der unix epoche" hier ein link dazu: UNIX EPOCHE Zitieren
Empfohlene Beiträge
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.