Hallo,
hat Jemand eine Idee, wie ich aus der Wettersoftware Cumulus die aktuelle Tagestemperatur vor einem Jahr auf meinem Webspace ausgeben kann?
D.h. ich würde gerne neben der aktuellen Temperatur auch die Temperatur anzeigen, wie sie genau vor einem Jahr zu dieser Zeit war.
Man sagte mir, dass das irgendwie mit SQL gehen könnte, doch habe ich von SQL keine Ahnung.
hab diesbezüglich mal etwas gegoogelt und bin darauf gestoßen, kann ich mein Vorhaben ggf. damit umsetzen:
http://wiki.sandaysoft.com/a/ImportCumulusFile
oder vielleicht gibt es noch eine einfacherer Möglichkeit über PHP?
denn Cumulus liefert eine txt-Datei in der alle Messwerte gespeichert sind.
Jetzt müsste ich nur aus dieser txt-datei den entsprechenden wert auslesen, doch wie man das realisieren kann, weiß ich leider nicht, ich hänge hier mal einen Auszug dieser txt-Datei an:
22.01.15;20:25;1,2;98;0,9;2,5;5,0;46;0,0;0,0;1016,9;0,6;23,4;25;5,0;1,2;1,2;0;0;0,00;0,00;-1,1;0;0,0;45;0,0;0,0
22.01.15;20:26;1,4;98;1,1;4,4;7,2;82;0,0;0,0;1016,9;0,6;23,4;25;7,2;1,4;1,4;0;0;0,00;0,00;-1,3;0;0,0;90;0,0;0,0
22.01.15;20:27;1,2;98;0,9;5,2;7,2;67;0,0;0,0;1016,9;0,6;23,4;25;7,2;-0,3;1,2;0;0;0,00;0,00;-1,6;0;0,0;45;0,0;0,0
22.01.15;20:28;1,2;98;0,9;4,6;7,2;71;0,0;0,0;1016,9;0,6;23,4;25;6,1;1,2;1,2;0;0;0,00;0,00;-1,5;0;0,0;360;0,0;0,0
Der Wert den ich ausgeben möchte, ist der erste Wert nach dem Datum und der Uhrzeit, das ist die Temperatur.
Jetzt müsste ich wissen, wie ich in der txt-Datei auf die entsprechende Zeile zugreifen könnte und zwar abhängig von der aktuellen Uhrzeit müsste mein Script dann immer die entsprechende Zeile mit der entsprechenden Uhrzeit und dem Datum vor einem Jahr aufrufen und dort dann den ersten Zahlenwert ausgeben.
Ist so etwas möglich?
Kann mir hier vielleicht Jemand weiter helfen?
Danke für die Infos
Gruß Frank
Hallo,
bei mir ist es mitlerweile schon 5 Jahre her das ich Cumulus verwendet habe.
Damals habe ich meine Daten genau mit der Prozedur ins SQL bekommen.
Habe die Daten dann aus der Dayfile ausgelesen und ins SQL übertragen.
Das ging dann mit dem Link der im Wiki angegeben ist.
Zusätzlich hatte ich dann noch eine Webpage die, die Werte in einer Tabelle angezeigt hat.
Diese Tabelle konnte man dann nach seinen Bedürfnissen anpassen.
Die Tabelle habe ich damals von einem User der im Sandysoft Forum unterwegs war bekommen.
Such mal im Forum bei sandysoft ob es zu der Tabelle noch einen alten Beitrag gibt.
*UPDATE* Ich habe den Beitrag gefunden. Das war die historic.php
http://sandaysoft.com/forum/viewtopic.php?f=18&t=2373
http://sandaysoft.com/forum/viewtopic.php?f=18&t=2367
Der Autor von der historic.php ist "daj". Soweit ich gesehen habe ist der noch Aktiv und betreibt auch noch eine Wetter Seite. Vielleicht kannst du über ihn die benötigte Dateien beziehen.
Anbei noch ein Beispiel von einem User der die Tabelle verwendet.
http://weather.gktnet.com/history_php.php
Grüße
Werner
Hallo,
vielen dank für deine Ausführungen, doch ich glaube das Unterfangen wird für mich etwas zu kompliziert, denn ich habe bezüglich SQL NULL Kenntnisse ;-(
Vielleicht geht es ja auch irgendwie einfacher, da ich ja keine komplette Tabelle benötige, ich will ja lediglich aus der txt.-Datei die Temperatur auslesen, die zum aktuellen Zeitpunkt vor einem Jahr herrschte, d.h. ich müsste irgendwie über das aktuelle Datum (minus 1 Jahr) sowie der aktuellen Uhrzeit in die entsprechende Zeile der txt.-Datei springen und dann aus dieser Zeile dann die Temperatur auslesen.
Gruß Frank
Hallo Frank,
bevor Du die Flinte ins Korn wirfst, vielleicht noch eine kleine Anmerkung zu der Datenspeicherung in .txt- oder .csv-Dateien:
Diese Dateien verwenden keine feste Datensatzlänge, so dass man z.B. ab Anfang der Datei immer nur z.B. 138 Byte Offset addieren könnte, um auf den nächsten Datensatz zu gelangen.
Die Datensatzlänge hängt stets von den Formatierungen des Datums und auch der Größe der Messwerte ab. Wenn z.B. ein Temperatur von 1,2 (° C) auftritt, benötigt die 3 Byte zur Darstellung, ein Wert von 12,4 aber 4 Byte oder ein Wert von -10,8 5 Byte. Die Datensatzlänge variiert also mit den Daten und da kann man nicht wirklich indizieren, um genau den gewünschten Datensatz zu treffen.
Andererseits ist jeder Datensatz mit einem Lf (Linefeed, UNIX-typisch) oder der Zeichenkombination CrLf (CarriageReturn + Linefeed, DOS- oder Windows-typisch) abgeschlossen. Wenn man einen bestimmten Datensatz sucht, müsste man zeichenweise über die komplette Datei scannen, um das N-te Vorkommen der Schlusszeichen (Lf oder CrLf) zu finden und damit den Anfang des Datensatzes N+1 zu bestimmen. Mit intelligenten Suchkriterien ließe sich das zeitlich optimieren, indem man eine binäre Suche definiert (die den Suchbereich immer halbiert, um auf einen Treffer zu gelangen), aber dafür sind .txt- oder .csv-Dateien eher weniger gedacht - die lassen sich am Besten nur linear von vorne bis hinten abarbeiten, um die enthaltenen Daten in Tabellen oder Grafiken zu übertragen. Hier einen bestimmten Datensatz zu suchen, wird schnell zu einer komplexen Aufgabe, weil man ja nicht wie bei "fester Datensatzlänge" einfach mit einem Offset arbeiten kann, um auf den nächsten Datensatz zu gelangen.
Daneben stellt sich das Problem, dass Datumsformate (anscheinend in Cumulus einstellbar), unterschiedlich gestaltet sein können also z.B. YYYYMMDD oder auch DD.MM.YY(YY), die Zeit auch anstelle von hh:mm:ss als 9:38:00 am oder 9:38:00 pm in der Datei abgelegt sein könnten, was man bei einer Suche nach dem "richtigen" Datensatz zusätzlich berücksichtigen müsste.
Desweiteren wird angloamerikanisch mit dem "." als Dezimaltrenner gearbeitet, in Europa meist mit "," wobei ich nicht weiß, wie intelligent die Ablage in eine SQL-Datenbank damit umgeht. Die braucht eventuell den Dezimalpunkt "." bei zu übertragenden Werten und nicht das Dezimalkomma ",".
Direkt auf eine indizierte Zeile zu "springen", kannst Du bei .txt- oder .csv-Dateien getrost vergessen - da braucht's zusätzliche Feinarbeit, um einen gewünschten Eintrag in der Datei wirklich zu treffen und "einfach" auswerten zu können - kein Hexenwerk (in C++ wüsste ich, wie ich vorgehen müsste), aber bei PHP oder betreff der Anbindung an eine SQL-Datenbank muss ich einfach passen, weil ich davon keine Ahnung habe.
Gruß Hans
Hallo Hans,
danke für deine ausführlicher Erklärung.
Ich will ja nicht gleich die Flinte ins Korn werfen, hab ja auch die anderen Dinge, was meine Homepage angeht, mit anfänglich NULL Ahnung, nur durch Hilfe von Forenkollegen und viel nachlesen im Internet geschafft.
Aber mein Vorhaben, was sich anfangs für mich so einfach anhörte, scheint doch wesentlich komplizierter als gedacht zu sein und ich glaube, dass sich wegen der Kleinigkeit, d.h. die Temperatur von vor einem Jahr anzuzeigen, der Aufwand nicht lohnt.
Wär eine nette kleine Spielerei gewesen, wenn man neben der aktuellen Temperatur auch immer noch die Temperatur von vor einem Jahr gesehen hätte, denn oftmals fragt man sich ja "wie war es heute noch mal vor einem Jahr?", doch wie gesagt, ich glaube da steht "Nutzen" und "Aufwand" in keiner Relation zu einander.
Gruß Frank
Hallo Frank.,
Zitatich glaube da steht "Nutzen" und "Aufwand" in keiner Relation zu einander.
So ist es. Ohne Kenntnisse von PHP wirst Du hier nichts erreichen und das eignet man sich nicht mal schnell so in 2 Wochen an.
Hallo Frank,
das ist mit PHP lösbar (ohne den Umweg über eine SQL-Datenbank).
Da ich nur sporadisch PHP nutze, habe ich die erforderlichen Befehle nicht alle parat.
Grundsätzlich müsste das so aussehen:
Das aktuelle Datum/Uhrzeit erfassen, 1 Jahr davon abziehen;
dabei müsste geklärt werden, wie mit dem 29.2. umgegangen wird.
Umwandeln in das Format, in dem es in der txt-Datei vorliegt, also bei dir "TT.MM.JJ;HH:MM".
Mit fopen die txt-Datei öffnen
In einer Schleife mit fgets die Zeilen einlesen
Die ersten 14 Zeichen jeder Zeile mit dem Datumstring vergleichen bis zum Treffer
Ist die Zeile gefunden, die Zeichen ab Pos. 16 bis vor dem nächsten Semikolon extrahieren
Das ist dann der gesuchte Wert.
Hallo,
prinzipiell mal die Frage zur Abfrage mit PHP, ist diese Abfrage überhaupt realistisch?
Denn die Datenbank enthält für jede Minute einen Eintrag, d.h. wenn PHP dann die Datums und Uhrzeit durchsuchen muss, bis es an der richtigen Stelle angekommen ist, wäre wenn man die txt-Datenbänke monatlich durchsuchen würde, ja schon ein mega großer Suchdurchlauf.
Nehmen wir mal an es wäre der 31. eines Monats und es wäre 23:59 Uhr dann müssten insgesamt fast 45 000 Einträge durchlaufen werden bis man beim richtigen Eintrag ankommt (60 Einträge pro Stunde, das mal 24h und dann mal 31 Tage).
Gruß Frank
Realistisch schon da Du ja den Wert von vor einem Jahr haben willst. Vielleicht ist das Durchsuchen der CSV aber nicht mehr performant genug - da gilt es letztlich zu experimentieren und Aufwand/Nutzen/Laufzeit zu prüfen. Mit einer SQL-DB wäre es sicher schneller, da man dort ganz andere Abfrage-Möglichkeiten hat.
Wenn Du es dennoch ausprobieren willst, hier mal ein möglicher Schnellansatz ohne Fehlerprüfungen etc. - Gibt viele Wege zum Ziel ;)
<?php //Datum und Zeitangaben date_default_timezone_set('Europe/Berlin'); $now = time(); $past = strtotime(date('d-m-Y H:i', $now) . ' - 1 year'); // Cumulus-Textdatei einlesen $lines = file('cumulus.txt'); foreach ($lines as $row){ $row = explode(';', $row); $teileDat = explode('.',$row[0]); $teileZeit = explode(':',$row[1]); $datstamp = mktime($teileZeit[0],$teileZeit[1],'00',$teileDat[1],$teileDat[0],$teileDat[2]); if($datstamp === $past){ // Treffer gefunden echo '<strong><font color="red">'.$datstamp.' -- Passt!</font></strong><br>'; } else { // Kein Treffer echo $datstamp.' -- Passt nicht<br>'; }}?>
Ergänzung:
Ein kleiner Test auf meinem Server ergab eine Scriptlaufzeit im Schnitt von 0.3 Sekunden.
Als Grundlage habe ich eine Textdatei erzeugt, die für einen Monat minütliche Werte beinhaltet.
Wenn das Parsen einer Textdatei zu langsam und die Installation einer relationalen Datenbank zu aufwändig ist, dann lohnt es sich im Allgemeinen SQLite3 in Betracht zu ziehen.
@Rene
Danke für deinen Code, habe ihn gerade mal ausprobiert, funktioniert leider nicht, es kommt das dabei raus (auszug, habe die Datei etwas gekürzt):
Zitat
1421954700 -- Passt nicht
1421954760 -- Passt nicht
1421954820 -- Passt nicht
1421954880 -- Passt nicht
1421954940 -- Passt nicht
1421955000 -- Passt nicht
1421955060 -- Passt nicht
1421955120 -- Passt nicht
1421955180 -- Passt nicht
1421955240 -- Passt nicht
1421955300 -- Passt nicht
1421955360 -- Passt nicht
1421955420 -- Passt nicht
1421955480 -- Passt nicht
1421955540 -- Passt nicht
1421955600 -- Passt nicht
1421955660 -- Passt nicht
1421955720 -- Passt nicht
1421955780 -- Passt nicht
1421955840 -- Passt nicht
1421955900 -- Passt nicht
1421955960 -- Passt nicht
Die obige Abfrage ging jedoch rasend schnell, d.h. wenn es darüber realisierbar wäre, könnte ich das vielleicht auch hin bekommen, da ich mich mit PHP ja schon etwas befasst habe und wenn mir Jemand die Grundbausteine liefert, bekomme ich das vielleicht mit etwas Hilfe hin.
Dein Code liest ja das aktuelle Datum und Uhrzeit ein, zieht 1 Jahr davon ab und durchsucht dann die txt-datei nach dem Treffer, das scheint für mich "durchschaubar" zu sein, da ich ja via PHP ja schon mal so eine Abfrage realisiert habe, damals gings um den metar-Code vom Flugplatz durchzulesen und darüber die aktuelle Wolkenbedekung auszugeben, das ist ja eine ähnliche Abfrage.
Danke
Gruß Frank
Na ja,
vielleicht stimmt das Datumsformat noch nicht oder die Minute wird nicht auf den Punkt getroffen, das meinte ich in einem früheren Statement mit dem Hinweis auf das zu verwendente Datumsformat.
Der Hinweis von renè passt schon, aber Du musst dich selbst noch auf die Anpassung auf Deine eigenen Datei damit beschäftigen und probieren.
Gibt's bei PHP-Entwicklungen nicht so was wie einen Debugger, mit dem man jeden Programmschritt irgendwie (auch bezüglich der zu erwartenden und zurück gelieferten Werte) nachverfolgen kann?
So einfach "reinkopieren" mit dem Kommentar, Du hättest das früher schon mal erfolgreich mit einer Abfrage zur "Wolkenbedeckung" durchgeführt, aber "hier" würde es nun nicht funktionieren, entbehrt anscheinend einer weiteren Beschäftigung mit PHP-Programmierung.
Wie gesagt - für mich ist PHP weitestgehend unbekannt - aber auf jedem System gibt es einen Debugger, mit dem man Zeile für Zeile den Erfolg gewünschter Operationen 1:1 nachverfolgen kann. Mit "Ausprobieren" eines Codes alleine, wirst Du nicht deutlich weiter kommen.
Gruß Hans
So wie Hans schreibt, wird höchstwahrscheinlich das Datumsformat nicht so ganz passen, wahrscheinlich beim Jahr - dürfte aber anzupassen sein - kannst ja mal ne komplette Datei bereitstellen, dann kann ich nochmal schauen.
@rene
Hast eine PN
EDIT 27.01.:
Webworker hat es mittels PHP-Script hin bekommen, Laufzeit für die Abfrage gerade mal 0,1Sekunden, denke das ist absolut vertretbar.
Skript funktioniert einwandfrei.
Danke noch mal an Webworker für seine klasse Hilfe.
Zitat von: TheWeather am 26.01.2016, 09:48:13
Gibt's bei PHP-Entwicklungen nicht so was wie einen Debugger, mit dem man jeden Programmschritt irgendwie (auch bezüglich der zu erwartenden und zurück gelieferten Werte) nachverfolgen kann?
Es gibt bei PHP eine Vielzahl an Möglichkeiten, entsprechend Debugging zu betreiben.
Die einfachsten sind das Error Reporting vom jeweiligen Webserver anzupassen, sein Script dahingehend zu ergänzen das an bestimmten Stellen entsprechende Ausgaben erfolgen. Es gibt auch spezielle Debugger dazu.
Anpassung des ErrorReporting zur Laufzeit, was bei einfachen Scripten oftmals hilfreich sein kann:
Als eigenständige Datei abspeichern und darin das jeweilige Script inkludieren:
<?phperror_reporting(E_ALL);ini_set('display_errors', 1);include('scriptname.php');?>
Auch von mir ein liebes Dankeschön an Rene. :top: Er hat mir auf PN-Anfrage hin bereitwillig wertvolle Tipps zum Einstieg in die PHP-Programmierung gegeben.
@Frank (Wetterfrosch1971): Kannst Du kurz beschreiben, wo der Haken war, dass es bei Dir bislang nicht funktionierte? ;) Aus Neugierde und für die mitlesende Nachwelt ... Danke.
Gruß Hans
Hallo Hans,
da musst Rene fragen, denn er hatte mir dann eine überarbeitete Version gesendet, die dann einwandfrei funktionierte, ich habe die alte und die neue Version jetzt nicht verglichen, ich war froh dass die neue Version funktionierte und somit überschrieb ich die alte Version.
Aktuell kann man nun den Messwert, den ich mit dem Script von Rene generiere auf dieser Seite meiner Homepage sehen (ist der Wert, der in der Temperaturspalte in Klammer steht, d.h. dieser wert ist die gemessene Temperatur zum aktuellen Zeitpunkt MINUS 1 Jahr, d.h. letztes Jahr um diese Zeit):
http://www.wetterstation-badenweiler.de/wetter/index.php
ich musste dazu jedoch die index von htm auf php umbennenen und einen kleinen "Umweg" in cumulus einschlagen, damit die index auch mit der Endung php funktioniert.
Cumulus speichert Datum/Zeit als String ohne Sekunden ab - es wurde quasi daraus immer ein Timestamp mit Sekunde 0 generiert. Als aktueller Vergleichwert wurde ein Timestamp generiert, der die tatsächliche Sekunde berücksichtigt - Die Vergleichsprüfung basiert jedoch auf dem exakten Timestamp, so konnte die Sekundendifferenz dann die Anzeige des Wertes verhindern.
Gelöst habe ich es mit folgenden Code-Zeilen falls es jemand interessiert:
<?php $now = time(); // Timestamp mit genauen Sekunden $now -= $now % 60; // Timestamp gerundet auf Sekunde 0 $past = strtotime(date('d-m-Y H:i', $now) . ' - 1 year'); // gerundeter Timestamp - 1 Jahr?>
Da es so funktioniert, ein möglicher Weg zum Ziel :)
Danke Rene, da wird mir Einiges klarer. Weiter unten hier (http://www.wetterstationen.info/forum/allgemeines-softwareforum/sql-datenbank-temperatur-vor-einem-jahr-aus-cumulus-auslesen/msg284398/#msg284398) hat Bernd aber noch ein weiteres Phänomen angesprochen, nämlich den 29.2. (Februar), zu dem es in Schaltjahren ein Problem geben wird, weil kein Vorjahreswert gefunden werden kann.
Das ist zwar nur eine kleine Lücke von einem Tag, aber am 29.2. wäre in einem Schaltjahr kein Vorjahreswert verfügbar. Man könnte jetzt (ersatzweise) den Wert vom 28.2. oder vom 01.03. des Vorjahreswerts nehmen (oder auch den Mittelwert aus beiden), damit ein Vorjahreswert angezeigt werden könnte, ansonsten müsste man "---" einsetzen, weil es keinen Vorjahreswert gibt. Irgendwie müsste dieser Sonderfall aber tatsächlich noch gehandelt werden, bevor eine Fehlermeldung oder ein Absturz (gibt's sowas bei PHP) auftreten könnte.
Ansonsten - schöner Lösungsansatz, der geradlinig zum Erfolg führte.
Gruß Hans
P.S.: Ich könnte mir also vorstellen, dass man den 29.02 (als aktuelles Datum) zunächst erkennt, dann a) auf den 28.02. zielt, von dort die Temperatur nimmt, auf den 01.03. weiter zielt, von dort ebenfalls die Temperatur nimmt, den Mittelwert bestimmt und damit die Temperatur zum 29.02. als Mittelwert aus beiden als Vergleichswert ansetzt. Damit hätte man wenigstes einen realistisch gewonnenen Vergleichswert. Oder man erkennt b) gleich, dass es zum 29.02. kein Pendat aus dem letzten Jahr gibt und setzt direkt "---" ein.
a) wäre vielleicht ein wenig geschummelt, aber man hätte wenigstens einen Vergleichswert, b) wäre meines Ermessens die richtige Variante, weil es im Vorjahr einfach keinen 29.02. gab ... zumal das Ereignis ja nur alle vier Jahre auftritt. Wie man das nun macht, ist eventuell "Geschmachssache", aber beschäftigen muss man sich schon mit diesem kleinen Problem.
Gruß Hans
Moin Hans,
ja in der Tat wird es am 29.02. ein Problem geben wie Bernd geschriebn hat - man könnte Deinen Ansatz da verfolgen mit Berechnung einer möglichen Temperatur oder einfach wie der Threaersteller letztlich verfährt: Am 29.02. erfolgt schlicht und einfach keine Ausgabe der entsprechenden Daten.
Ebenso könnte man einfach den Hinweis geben bzgl. Schaltjahr - das kommt halt auf den Kontext an, wo entsprechendes verwendet und angezeigt werden soll. Ich persönlich würde da wohl auch die Variante der "- - -" wählen :top:
Hallo,
als nicht Betroffener:
ZitatIch persönlich würde da wohl auch die Variante der "- - -" wählen
So sehe ich das auch. Ich habe beispielsweise einen Ticker auf meiner Wetterseite, der von Meteohub gespeist wird. Und wenn der Mal, aus irgendwelchen Gründen keinen Wert liefert, würde dann im Ticker die entsprechende Variable ([actual_th0_temp_c:--], die den Wert erzeugt erscheinen, also sehr unschön. Auch da habe ich zu der Lösung "---" gegriffen.
Hallo,
bei mir als "Betroffener" sieht das so aus:
Das Script vergleicht ja das aktuelle Datum (minus 1 Jahr) mit dem Datum des letzten Jahres über eine if/else Bedingung, d.h. findet das Script einen Treffer, wird die Anweisung unter "if" ausgegeben (= die Temperatur des letzten Jahres wird ausgegeben), gibt es keinen Treffer (wie z.B. dieses Jahr am 29.02.), dann wird die "else-Bedingung" ausgeführt und über diese Bedingung gebe ich einfach ein leeres Feld aus, d.h. auf meiner Webseite wird dann an diesem Tag einfach der komplette Eintrag "Temperatur von vor einem Jahr ...°C" nicht angezeigt.
Denke das ist die einfachste und auch logischste Möglichkeit und dass nun an einem einzigen Tag dieser Wert mal fehlt, finde ich kein Beinbruch, denn es gibt ihn ja in Wirklichkeit auch nicht.
Klar könnte man nun entweder auf den 28.02. oder 01.03. zugreifen (korrekt wäre ja der 01.03., denn dieser war genau ein Jahr vor dem 29.02. des aktuellen Jahres Tage), doch wenn man das so genau nimmt, dann müsste ich ab dem 29.02. ja genau genommen immer 364 Tage abziehen um den genauen Vergleichswert zu bekommen, denn z.B. war ja genau 1 Jahr vor dem 01.03.2016 der 02.03.2015 (da 2016 ab dem 29.02. ja ein Tag mehr hat) doch ich denke, das ist dann zu penibel genau.
Ich vergleiche einfach den heutigen Tag nach Datum und Uhrzeit mit dem gleichen Datum und Uhrzeit des vergangenen Jahres und den 29.02. gibt es dabei schlicht und einfach nicht und deswegen wird an diesem Tag kein Wert ausgegeben.
Nicht, weil ich drauf rumreiten will, aber doch noch eine Frage zum Verständnis, was es mit dem Eintrag ' - 1 year' bei der Funktion strtotime auf sich hat.
Zitat von: webworker am 27.01.2016, 19:40:48
<?php $now = time(); // Timestamp mit genauen Sekunden $now -= $now % 60; // Timestamp gerundet auf Sekunde 0 $past = strtotime(date('d-m-Y H:i', $now) . ' - 1 year'); // gerundeter Timestamp - 1 Jahr?>
Wird da von der in $now enthaltenen Jahreszahl direkt ein Jahr abgezogen (also Jahreszahl - 1) oder werden an dem TimeStamp in der Regel die einem "normalen" Jahr (365 Tage * 86400 sec/Tag) entsprechenden sec abgezogen? Anders gefragt: Wie definiert PHP den Zeitraum "1 Jahr"? Weiß PHP, ob es normal 365 Tage oder in einem Schaltjahr ab dem 29.02. nun 366 Tage abziehen muss, um auf das gleiche Datum, nur ein Jahr zuvor, zu kommen?
Die Frage klingt vielleicht "blöde", aber welches Datum kommt denn dabei heraus, wenn man $past ebenfalls anzeigen würde? ;) Nicht dass hier Daten vom Vortag eines heutigen Datums (vor einem Jahr) als Vergleich zum heutigen Datum angegeben würden.
Das ist nicht wirklich entscheidend, aber wenn's jemand weiß (webworker?), würde mich das generell interessieren (1 Jahr ist ja keine genau definierte Zeitangabe im Sinne eindeutig definierbarer Zeitabschnitte).
Gruß Hans
Hallo Hans,
also ich kann zumindest soviel aussagen, dass das Script funktioniert, habe die ausgegebenen Temperatur-Werte verglichen, es sind exakt die Temperatur-Werte die exakt heute vor einem Jahr waren, d.h. die Funktion "-1 year" funktioniert.
Wie das Script jedoch beim aktuellen Datum das "-1 year" verarbeitet, weiß ich nicht, doch dazu kann sicherlich webworker mehr aussagen.
Gruß Frank
Hallo Hans,
Zitataber welches Datum kommt denn dabei heraus, wenn man $past ebenfalls anzeigen würde?
ich antworte mal so ganz profan: PHP weiß zeitmäßig alles und berücksichtigt auch alles.
Was heißt das für das genannte Beispiel (habe es mal schnell durchlaufen lassen:
Wenn Du das oben genannte script ausführst und die Werte mit 'echo' ausgibst, erhältst Du zunächst natürlich nur den Unix-Timestamp (Beispiel ist natürlich auf den Zeitpunkt bezogen, an dem ich das skript jetzt gerade habe laufen lassen )
Der Wert $now erbringt
1454004474
und der Wert $past erbringt
1422468420
Das hilft Dir zunächst gar nichts, aber PHP weiß, was gemeint ist.
Und wenn Du nun wiederum, was für die Berechnung nicht notwendig ist, aber damit Du einen Antwort auf Deine Frage hast, diese Werte in unser Zeitformat wandelst, erhältst Du für den Wert $now
28.01.2016 - 19:07:54
und für den Wert
$past (und das ist ja Deine Frage)
28.01.2015 - 19:07:00
(weil ja auf Sekunde Null gerundet wird)
Fazit:
Wer mal ein bisschen mit PHP gearbeitet hat (und ich bin da eher noch ein Stümper) wird mit Erstaunen feststellen, dass sich damit Dinge machen lassen, die man nicht für möglich hält.
Du brauchst ja nur mal die Seite
http://www.selfphp.de/funktionsreferenz/index.php
aufrufen und Du wirst staunen.
Hallo Werner, Du hast "meine Problemstellung" zumindest erfasst.
Ich kann's selbst leider nicht ausprobieren, weil ich erst am Anfang bin, mich mit PHP befassen zu wollen. Wenn ich Dich nochmal nerven darf - Was ergibt der gleiche Test für den 29.02.2016 und mit etwas Abstand am 18.03.2016? Es mag ja sein, dass PHP das "intern" vorzüglich löst, ich möchte aber auch verstehen, wie ...
Da hilft mir der Link vom letzten Beitrag erstmal weniger (ich hab' schon mal rein geschaut), da braucht's für mich eher einen knallharten Beweis, dass "1 Jahr" tatsächlich auch das Vorjahresdatum tatsächlich trifft - auf Sekunden kommt's hier nicht natürlich nicht an. Wie gesagt, "1 Jahr" ist keine anerkannte Zeitspanne, die irgendwo exakt festgelegt wäre.
Sorry, wenn ich wegen einer solchen Kleinigkeit nerve, aber ich will's ja auch verstehen ...
Gruß Hans
P.S.: Andererseits, wenn ich mal selbst etwas fitter in PHP bin, kann ich's ja selbst herausfinden. Sooo dringend ist es ja nicht. Wenn's niemand auf Anhieb beantworten kann, ist das nicht weiter schlimm. Ich hab' halt auch diese Frage mal in den Raum gestellt, mehr nicht.
Und ich frage mich, was da wohl am 29.02.2016 (ich hab da nicht Geburtstag :D ) passiert?
LG
WeatherCrack
Zitat von: TheWeather am 28.01.2016, 20:01:39
P.S.: Andererseits, wenn ich mal selbst etwas fitter in PHP bin, kann ich's ja selbst herausfinden. Sooo dringend ist es ja nicht.
Das ist doch eine berechtigte Frage. Mit der interaktiven Shell (php -a) lässt sich das schnell prüfen.
echo date("Y-m-d", strtotime("2016-02-28 -1 year")); => 2015-02-28
echo date("Y-m-d", strtotime("2016-02-29 -1 year")); => 2015-03-01
echo date("Y-m-d", strtotime("2016-03-01 -1 year")); => 2015-03-01
echo date("Y-m-d", strtotime("2016-03-02 -1 year")); => 2015-03-02
Hallo Hans,
falk ist mir freundlicherweise zuvorgekommen.
Nun also nur noch die Antwort zu Deiner letzten Frage:
Zitatund mit etwas Abstand am 18.03.2016
Das ergibt dann natürlich
2015-03-18
Hallo falk und Werner,
viele Dank für eure Hilfe. Jetzt hab' ich's kapiert ...
Für die Aufgabenstellung von Frank (wetterfrosch1971) heißt das aber, dass die Daten am 29.02.2016 (automatisch) mit denjenigen vom 01.03.2015 verglichen werden. Das ist ja auch so in Ordnung, dann gibt es aber auch am 29.02.2016 einen Treffer im Vorjahr (nämlich den 01.03.2015) und die Anzeige bleibt nicht leer (oder "---").
Viele Dank nochmal.
Gruß Hans
Hallo Hans,
ja, dem wird dann wohl so sein, d.h. wenn es einen Treffer gibt, dann wird die Ausgabe ja "true" und nicht "false" und somit wird eine Ausgabe generiert.
Das ist dann so doch auch ok, wusste bis dato auch nicht, dass PHP so schlau ist und exakt 1 Jahr zurück rechnet und beim Schaltjahr dann einfach 2x den 01.03. verwendet, das passt für mich aber auch, dann wird halt am 29.02. und am 01.03. jedes mal die Temperatur vom Vorjahres-ersten-März ausgegeben.
Gruß Frank
Vielleicht ist der Aufwand für den einen Tag in 4 Jahren übertrieben, aber man könnte auch statt
"vor einem Jahr" angeben: "am 01.03.2015".
Dann wären alle Zweifel beseitigt, welcher Tag vor einem Jahr zugrunde gelegt wurde.
Hallo,
ich würde es sowieso interessanter finden (aber das ist Geschmackssache), nicht den Temperaturwert zu einer genauen Uhrzeit sondern den Durchschnittswert des jeweiligen Tages zu vergleichen. So mache ich es zumindest auf meiner Seite mit einer einzigen Variablen von WSWIN und ganz ohne PHP. :)
Denn was sagt es schon, wenn es um eine bestimmte Uhrzeit gerade mal +2 Grad gehabt hat, der Durchschnittswert des ganzen Tages aber -5 Grad ist (es also ein ziemlich kalter Tag war).
Das soll jetzt aber keine Diskussion auslösen, die von der eigentlichen Fragestellung wegführt.
[gelöscht durch Administrator]
Zitatich würde es sowieso interessanter finden (aber das ist Geschmackssache), nicht den Temperaturwert zu einer genauen Uhrzeit sondern den Durchschnittswert des jeweiligen Tages zu vergleichen
Ja stimmt, ist reine Geschmackssache, ich finde es halt interessant, wenn ich schaue, wie die aktuelle Temperatur im Moment ist, wie sie exakt vor einem Jahr zum Vergleich war.
Sicherlich sagt die Durchschnittstemperatur eventuell mehr aus, doch leider bietet mein Wetterprogramm Cumulus in den log-Dateien keine Durchschnittstemperatur an, d.h. mein Programm verfügt nur über diese Durchschnittstemperatur "heute" und "gestern", weiter zurück wird diese Temperatur von Cumulus leider nicht gespeichert.
Hätte ich die Durchschnittstemperatur als log-Datei, würde ich sie auch noch anzeigen.
Gruß Frank
Hallo,
ich poste hier mal das fertige Script von webworker, falls vielleicht Jemand mal das selbe Vorhaben hat.
Das Script ist auf die Parameter die das Wetterprogramm Cumulus produziert ausgelegt.
Damit das Script funktioniert, muss man auf den Webspace, in den selben Ordner wie das Script, die monatlichen Cumulus log Dateien des vergangenen Jahres hochladen (sind unter Cumulus im data-Ordner zu finden und heißen z.B, jan15log.txt)
Diese 12 monatlichen Dateien muss man dann auf dem Webspace in january.txt, february.txt usw. (alles klein geschrieben) umbenennen, sonst funktioniert das Scrip nicht.
Außerdem ist wichtig, welches Speicherintervall man bei den log-Dateien verwendet, das Script im Ursprungszustand arbeitet mit einem Speicherintervall von 1 Minute, d.h. es funktioniert nur, wenn die log-Datei von dem es die Temperatur von vor einem Jahr ausließt, alle Minute einen Wert gespeichert hat.
Hat man ein Speicherintervall von 10 Minuten in den log-Dateien, so kann man im Script eine Zeile abändern, so arbeitet es auch mit diesem Speicherintervall.
Danke an diese Stelle noch mal an webworker, der mir dieses schöne Script erstellt hat, es funktioniert super und hat mit 0,1 Sekunden Laufzeit denke ich keinen Einfluss auf die Geschwindigkeit beim Aufbau der Webseite.
Das fertige Script läuft bei mir auf dieser Seite:
http://www.wetterstation-badenweiler.de/wetter/index.php
<?php //Datum und Zeitangaben date_default_timezone_set('Europe/Berlin'); //$now = ceil(time()/600)*600; //Zeit auf 10 Minuten aufgerundet (für den Fall, dass log-Datei nur alle 10 Minuten einen wert liefert) //$now = = floor(time()/600)*600; //Zeit auf 10 Minuten abgerundet $now = time(); //für den Fall, dass log-Datei alle Minute einen Wert gespeichert hat $now -= $now % 60; $past = strtotime(date('d-m-Y H:i', $now) . ' - 1 year'); //Cumulus-Textdatei einlesen (muss auf dem Webspace als january.txt usw. vorliegen) $lines = file(strtolower (date('F')).'.txt'); foreach ($lines as $row){ $row = explode(';', $row); $teileDat = explode('.',$row[0]); $teileZeit = explode(':',$row[1]); $datstamp = mktime($teileZeit[0],$teileZeit[1],'00',$teileDat[1],$teileDat[0],$teileDat[2]); if($datstamp === $past){ echo 'Temperatur heute vor einem Jahr: '.$row[2].' °C<br>'; } else { // kein Ergebnis gefunden }}?>
Beiträge zusammengeführt, weil der Autor sich selbst geantwortet hat statt seinen letzten Beitrag zu ändern: 31.01.2016, 14:52:10
Zitat von: wneudeck am 29.01.2016, 16:32:48
Hallo,
ich würde es sowieso interessanter finden (aber das ist Geschmackssache), nicht den Temperaturwert zu einer genauen Uhrzeit sondern den Durchschnittswert des jeweiligen Tages zu vergleichen.
Hallo,
suche gerade nach einer Lösung, dies auch noch umzusetzen können, dazu benötige ich jedoch ein weiteres PHP-Script, denn in den log-Dateien wird bei mir nur die aktuelle Temperatur gespeichert (minütlich).
Jetzt muss ich ein Script haben, welches mir beim Aufrufen des Scriptes aus der Log-Datei die einzelnen Temperaturen seit 0 Uhr (des vergangenen Jahres) bis zur aktuellen Uhrzeit (des heutigen Tages im vergangenen Jahr) addiert und dann durch die Anzahl der Minuten (da jede Minute ein Temperaturwert gespeichert wurde) teilt und diesen Wert dann ausgibt, dann habe ich auch den Durchschnittswert und kann diesen anzeigen.
Falls dies zu viel Rechenarbeit wäre und somit die Laufzeit zu lang wird, könnte man statt jeden minütlichen Wert zu berücksichtigen, auch nur jeden Wert pro 10 Minuten berücksichtigen, somit wird die Rechenoption 10mal kürzer
Gruß frank
Zitat von: TheWeather am 28.01.2016, 18:03:12
Das ist nicht wirklich entscheidend, aber wenn's jemand weiß (webworker?), würde mich das generell interessieren (1 Jahr ist ja keine genau definierte Zeitangabe im Sinne eindeutig definierbarer Zeitabschnitte).
Gruß Hans
Hallo Hans, ich kann es Dir nicht genau sagen - soweit ich weiß arbeitet PHP intern mit den Sekunden des Timestamps. Vielleicht findest Du ja noch weitere Informationen zu den relativen Zahlenformaten und deren Behandlung in der PHP-Doku.
Ansonsten habe ich gerade noch eine Version an den Author des Thread gesendet, der die Durchschnittstemperatur vor einem Jahr versucht zu berücksichtigen - ist allerdings nicht ausreichend getestet...
dank webworker wird bei mir nun auch noch als Vergleichswert die Durchschnittstemperatur von vor einem Jahr mit der heutigen Durchschnittstemperatur verglichen/angezeigt, gugst du:
http://www.wetterstation-badenweiler.de/wetter/index.php
Hallo Rene,
Zitat von: webworker am 31.01.2016, 17:03:41
Hallo Hans, ich kann es Dir nicht genau sagen - soweit ich weiß arbeitet PHP intern mit den Sekunden des Timestamps.
Ich habe gerade mal probiert, die Thematik in C++ (Embarcadero) abzuarbeiten. Im Microsoft C++ gibt es eine Funktion zu DateTime, .AddYears(x) mit x = Integer + oder -, welche anscheinend ebenfalls alle Umstände berücksichtigt.
Bei der Klasse TDateTime im Embarcadero C++ gibt es kein entsprechendes Pendant, lediglich über Drittanbieter, welche dazu ebenfalls Units bereit stellen.
Um in der Klasse TDateTime zu einem zurückliegenden oder vorauseilenden Jahr gleichen Datums zu gelangen, braucht es wenigstens zwei Entscheidungen: Ist das Ausgangsdatum ein Schaltjahr (?) und liegt das Datum vor dem 01.03. des Jahres (?) oder danach.
Mit diesen Entscheidungen kann man mal 365 oder auch 366 Tage (Vorkommawert in TDateTime) addieren oder subtrahieren, je nachdem, ob das momentane Datum vor oder nach dem 01.03. eines Jahres liegt und ob das Ausgangsdatum ein Schaltjahr ist oder nicht. Je nachdem, ob es um ein oder mehrere Jahre (vor oder zurück geht) muss geprüft werden, ob ein Schaltjahr dazwischen liegt (2000 war ja bekanntlicherweise ein Schaltjahr, 1900 aber keins, also Regeln für Schaltjahre beachten). Mit all diesen Regeln kann man (bislang) auch 100te von Jahren addieren, allerdings nur wenige Jahrhunderte zurückrechnen, da es (ich meine es war 1563) mal ein Loch von 10 Tagen im Oktober gab, wo vom 06.10. direkt auf den 16.10. gesprungen werden musste, um irgendwelche Kalendarien anzugleichen.
Das Thema ist also schon interessant, für uns allerdings nicht mehr über Jahrhunderte zurück noch anwendbar, wenn ein Tool nicht Alles Dagewesene in der Zeitrechnung bereits berücksichtigt und die zukünftigen Entwicklungen natürlich noch nicht weiß. Es gibt also immer einen Wertebereich, der in einem Tool berücksichtigt sein müsste. Der hört nun aber nach unten nicht beim Jahr "0", Christi Geburt am 25.12.0000 auf (war das ein Dienstag oder ein Samstag) auf, sondern erst viel später im Mittelalter, seit dem unser "neues Datumssystem" etabliert werden konnte.
Erspart mir bitte weitere Recherchen und detaillierte Quellenangaben - mir ging's nur darum aufzuzeigen, mit welchen teils zwar detaillierten aber oft nur schwer zugänglichen Informationen bei Zeitumrechnungen zu rechnen ist. Kein Mensch kann mehr sagen, ob das Sauriersterben vor einigen Mio Jahren nun primär an einem Donnerstag oder einem Dienstag statt fand.
Dass morgen (heute ist der 01.02.) der 02.02. folgt, ist mittlerweile selbstredend. Ob am 01.03. diesen Jahres der vorangehende Tag der 29.02. oder der 28.02. war, lässt sich nur klären, wenn man weiß, ob dieses Jahr nun ein Schaltjahr ist.
PHP scheint das (für neuzeitliche Daten) tatsächlich im Griff zu haben - aber es gehört eine Menge Recherche dazu, hier wirklich Alles richtig zu machen, sobald es mal um Daten geht, die um Jahrhunderte zurückgreifen sollten. Nach oben hin ist noch Alles offen, aber auch da ist es vermutlich vermessen, jetzt schon zu bestimmen, ob der 24.12.2156 auf einen Donnerstag fällt oder doch eher auf einen Mittwoch, da weitere Korrekturen (die Erde dreht sich immer langsamer) bis dahin wohl zur Zeit noch nicht wirklich auf ihren Einfluss bezüglich des Datums erforscht sind.
Klingt vielleicht blöde oder auch utopisch, aber ich kenne keine Studien, inwieweit wir mit Schaltsekunden oder auch Schaltjahren im Bezug auf einige hundert Jahre in der Zukunft noch "up to date" sind.
Nichts Schlimmes, aber so ein paar Überlegungen dazu, dass Zeitumrechnungen immer fehlerbehaftet sein können, solange der Definitionsbereich nicht eindeutig in der heutigen Zeit liegt und der Wertebereich (das Ergebniss von Berechnungen) nicht eindeutig im Zeitrahmen definiert ist.
Da haben die Mayas wohl auch mal einen Strich gezogen, weswegen deren Kalender am 21.12.2012 endete. Keine Spur von Weltuntergang, aber immer noch die Erinnerung, "dass nichts bleibt, nichts bleibt, wie es war" - da waren die damals schon ziemlich schlau.
Das ist im Zusammenhang mit dem Thread vielleicht ziemlich "Off Topic", aber es gibt uns Allen gleichfalls das Recht, die Zeitrechnung nach eigenen Maßstäben zu interpretieren.
Es geht hier im Thread jedenfalls nur darum, einen knapp ein Jahr zurückliegenden Tag als Vergleich zu "heutigen" Verhältnissen zu zitieren und das ist so "voll in Odrdnung".
Gruß Hans
Angespornt vom ursprünglichen Thema habe ich, glaube ich jedenfalls, eine Lösung für meine MySQL-Tabelle gefunden.
In der Tabelle ist das Datum mit Zeitanteil als datetime (0000-00-00 00:00:00) abgespeichert.
Zunächst wird der Unix Timestamp vor einem Jahr im PHP-Skript ermittelt:
$lastyear = strtotime("-1 year");
Dann wird dieser Wert in das datetime-Format konvertiert:
$datuml = date("Y-m-d H:i:s", $lastyear);
Mit der Abfrage:
"SELECT tempout AS ljahrT
FROM tabelle
WHERE datetime <= '$datuml'
ORDER BY datetime
DESC
Limit 1");
Es wird der Temperaturwert vor einem Jahr, dessen Datum inkl. Zeitanteil entweder gleich bzw. eine Speicherung vor dem ermittelten Datum liegt, ausgegeben.
Hallo,
wobei aber bei
Limit 1");
die Klammer verschwinden sollte, denke ich.
Zitat von: wneudeck am 01.02.2016, 21:07:41
Hallo,
wobei aber bei
Limit 1");
die Klammer verschwinden sollte, denke ich.
Jein. Es fehlt aus der SELECT-Anweisung vorne noch $sql_letztesJahrT=mysql_query(... ;)
Übrigens, aktuel:
11.2°C (letztes Jahr 2.0°C)
Zitat von: GS63 am 01.02.2016, 20:55:09
Angespornt vom ursprünglichen Thema habe ich, glaube ich jedenfalls, eine Lösung für meine MySQL-Tabelle gefunden.
In der Tabelle ist das Datum mit Zeitanteil als datetime (0000-00-00 00:00:00) abgespeichert.
Zunächst wird der Unix Timestamp vor einem Jahr im PHP-Skript ermittelt:
$lastyear = strtotime("-1 year");
Dann wird dieser Wert in das datetime-Format konvertiert:
$datuml = date("Y-m-d H:i:s", $lastyear);
Mit der Abfrage:
"SELECT tempout AS ljahrT
FROM tabelle
WHERE datetime <= '$datuml'
ORDER BY datetime
DESC
Limit 1");
Es wird der Temperaturwert vor einem Jahr, dessen Datum inkl. Zeitanteil entweder gleich bzw. eine Speicherung vor dem ermittelten Datum liegt, ausgegeben.
Je nach Aufbau der Datenbank kann man auch direkt mit den Funktionen von MySQL arbeiten, ohne vorher Werte konvertieren zu müssen.
mysql> SELECT something FROM tbl_name
-> WHERE DATE_SUB(CURDATE(),INTERVAL 1 YEAR) <= date_col;
Siehe dazu: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html (http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html) und/oder http://www.w3schools.com/sql/func_date_sub.asp (http://www.w3schools.com/sql/func_date_sub.asp)
Nebenbei angemerkt: die Erweiterung "mysql_query" ist veraltet und dürfte irgendwann nicht mehr funktionieren... :eek:
Hallo Rene,
Zitat von: webworker am 02.02.2016, 08:14:50
WHERE DATE_SUB(CURDATE(),INTERVAL 1 YEAR) <= date_col;
Mit diesem Befehl wurde immer "nur" der erste Wert vom entsprechenden Tag mit dem Zeitanteil 00:00:00 angezeigt. Hat mich fast das ganze Wochenende gekostet... :confused:
Über die erste Konvertierung erhalte ich exakt den Tag vor einem Jahr inkl. Zeitanteil.
Zitat von: webworker am 02.02.2016, 08:14:50
die Erweiterung "mysql_query" ist veraltet und dürfte irgendwann nicht mehr funktionieren..
Hängt dies von der PHP-Version ab, die der Webhoster anbietet? Würde ein einfaches Umschreiben zu mysql
i_query reichen?
Gruß
Georg
Zitat von: GS63 am 02.02.2016, 08:33:51
Hängt dies von der PHP-Version ab, die der Webhoster anbietet? Würde ein einfaches Umschreiben zu mysqli_query reichen?
Gruß
Georg
Ja richtig, das liegt an der verwendeten PHP-Version vom Webhoster.
Einfaches Umschreiben alleine dürfte nicht reichen, auch die Verbindungsparameter sind anders.
http://php.net/manual/de/function.mysql-query.php