Florians Forum » Webmaster » Ideen für Skripte und sonstige Quellcodes » Durchschnittliche Beiträge

Hallo Florian,
das Script will nicht so recht funktionieren. Die Berechnungen sich auch nicht richtig. Je kleiner die Beitragszahl, desto großer die Abweichung.
Hier ist das gesamte Script. Ich habe an den Werten schon herumgeschraubt, aber die Beitragszahlen stimmen nicht. Hier muss ein Fehler in der Berechnung vorliegen! Wie kommt eigentlich die Zahl 86400 zu Stande? Stimmt die Berechnung für var tage überhaupt?
z.B Profil von floriwin: http://www.hilfe-tricks-tipps.de/u190_floriwin.html
2 Beiträge - Reg.: 18.04.2011 - müssten 1085 Tage sein >>>> 2/1085 x 365 == 0,67 Beiträge pro Jahr - angezeigt wird kleiner 0, obwohl eigentlich 2 Stellen nach dem Komma definiert sind.
<b>Beiträge:</b></td><td><div id="xanzeige"></div></td></tr>
{{posts==true.end}}
<script type="text/javascript" language="javascript">
var regdatum = new Date({{reged}});
var posts = {{posts}};
var jetzt = new Date();
var jetzt_UMT = jetzt.getTime()/1000;
var tage = Math.round((jetzt_UMT - regdatum)/86400);
var post_tag = Math.round(posts/tage*100)/100;
if(tage < 1 && tage < 7) {
if (post_tag > 0){
document.getElementById('xanzeige').innerHTML=' Ø ' + post_tag + ' pro Tag ';
}
else {
document.getElementById('xanzeige').innerHTML=' kleiner 0,0 pro Tag ';
}
}
else if(tage < 30) {
var post_woche = Math.round(post_tag*7*100)/100;
if (post_woche > 0){
document.getElementById('xanzeige').innerHTML=' Ø ' + post_woche + ' pro Woche ';
}
else {
document.getElementById('xanzeige').innerHTML=' kleiner 0,0 pro Woche ';
}
}
else if(tage < 365) {
var post_monat = Math.round(post_tag*30*100)/100;
if (post_monat > 0){
document.getElementById('xanzeige').innerHTML=' Ø ' + post_monat + ' pro Monat ';
}
else {
document.getElementById('xanzeige').innerHTML=' kleiner 0,0 pro Monat ';
}
}
else {
var post_jahr = Math.round(post_tag*365*100)/100;
if (post_jahr > 0){
document.getElementById('xanzeige').innerHTML=' Ø ' + post_jahr + ' pro Jahr ';
}
else {
document.getElementById('xanzeige').innerHTML=' kleiner 0,0 pro Jahr ';
}
}
</script>
Weist Du hier weiter?

Gruß
Wolfgang

Hi Wolfgang,
ich schätze mal, dass die Zeitspanne zwischen dem aktuellen und dem Registrier-Datum nicht ganz stimmen.
Ich habe dafür einiges ausprobiert und habe nun hier einen Beispiel-Code, welcher die korrekte Differenz in Tagen berechnen können sollte:
2
3
4
5
6
7
8
9
10
11
var posts = {{posts}};
var regdatum = new Date({{reged}} * 1000); // reged liefert Sekunden, ms für Date
var jetzt = new Date();
var differenz = jetzt - regdatum;
var tage = (differenz / (1000*60*60*24)); // ms in Tage umrechnen (differenz/86.400.000)
//console.log(regdatum.toGMTString());
console.log(regdatum.toLocaleString());
console.log(jetzt.toLocaleString());
console.log(tage);
Das Date-Objekt in JS erhält bei Erzeugung eigentlich eine Zeitangabe in ms (oder ein entsprechend formatierter String). Hier siehst du auch, wie die 86.400 zustande kommen (ein Tag in Sekunden, oben aber eben in ms). Beides auch nochmals unter JavaScript Dates nachzulesen.
Das Profil von floriwin existiert nebenbei gesagt bereits seit 1106 Tagen. Nur damit du beim manuellen Nachrechnen des Durchschnitts nicht zu Große Abweichungen erhälst. Evtl. unterscheidet sich diese Zahl um einen Tag, je nachdem ob man von heute oder noch gestern ausgeht und den gerade aktuellen Tag immer einberechnet. Du kannst es dir aber mit dem Tagerechner da etwas einfacher machen.
Ich empfehle dir nebenbei auch immer erst bei der Ausgabe zu runden, sonst würde z.B. bei 6,5 Tagen angenommen, eine ganze Woche wäre bereits erreicht. Aktuell bräuchtest du Monat und Jahr auch nicht wirklich runden, da die Tage bereits in eine Ganzzahl umgewandelt wurden, davon ausgehend, die Multiplikation und Division durch 100 könnte einfach wegfallen (deren Sinn habe ich noch nicht ganz verstanden ). Aber egal wie, mache besser keine Rundungen in den Berechnungen und Abfragen, erst in der Ausgabe für HTML. Als Nebeneffekt läuft das Skript schneller (wenn wohl auch kaum spürbar), da nur einmalig bei der entsprechenden Ausgabe gerunded wird und nicht immer noch vor der Prüfung.
Als letztes noch schmeiß ich mal noch rein, ob du im ersten IF nicht evtl. folgendes meintest: (tage > 1 && tage < 7)

Hallo Florian,
erstmal besten Dank für die schnelle Antwort.
Ich werde es ausprobieren.
Wolfgang

Hallo Florian,
ich habe den Fehler gefunden!
* Es fällt nur bei Beiträgen kleiner 1 erst richtig auf. Bei großen Foren und vielen Beiträgen kaum!
* Interessanterweise funktionieren beide Code-Beispiele.
* 100)/100; bewirken mit "Math.round " zusammen ein runden auf 2 Stellen nach dem Komma.
*******************************************************************************************
Die fehlerhafte Beerechnung liegt daran, dass von Anfang an "post_tag " gerundet wird. Alle anderen Berechnungen stützen sich auf "post_tag " und werden ein zweites Mal gerundet.
Ich hatte im Supportforum auch schon mal Mario gefragt:
http://www.hpm-support.de/t536359f117691...html#msg7255010

Hallo Wolfgang,
wahrscheinlich funktionieren beide Varianten, da bei deiner ersten das Datum mit Sekunden angelegt wird und du später nur durch 86.400 teilst. Bei meiner Variante habe ich ausgerechnet ja durch 86.400.000 geteilt, also gerade der Faktor 1000 zwischen Sekunden und ms. Dafür brauchte ich keine Variable jetzt_UMT, die auch noch durch 1000 geteilt werden musste, um auf Sekunden zu kommen. Bei der Berechnung von (jetzt_UMT - regdatum) wird eben die gleiche Einheit benötigt. Da Date aber generell mit ms arbeitet, würde ich auf jeden Fall zu der Variante tendieren. Sie ist später oder auch für andere beim Lesen des Skripts leichter verständlich, es muss nur klar sein, dass {{reged}} in Sekunden angegeben wird.
Bei der Multiplikation/Division mit/durch 100 dachte ich mir schon fast sowas. Allerdings hätte ich sowas wie Math.round(number, 2); eher erwartet. Aber JavaScript hat das wohl leider nicht.
Habe beim Suchen nach round übrigens einen ziemlich guten Thread entdeckt, hier mal ein Testcode, den ich mit den dortigen Infos kurz zusammengeschrieben habe:
2
3
4
5
6
7
8
9
10
var num = 1.005;
// http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-in-javascript/12830454#12830454
console.log(+num.toFixed(2));
// http://stackoverflow.com/questions/11832914/round-to-at-most-2-decimal-places-in-javascript/19722641#19722641
Number.prototype.round = function(places) {
return +(Math.round(this + "e+" + places) + "e-" + places);
}
console.log(num.round(2));
Die erste Methode rundet interessanterweise auf 1,0 statt 1,01. Das Plus-Zeichen sorgt dafür, dass der zweistellige String wieder in eine Zahl konvertiert wird und nur so viele Stellen darstellt, wie benötigt werden. Zweitere benötigt zwar die Definition einer Runden-Funktion für Zahlen, ist aber genauer und intuitiv zu handhaben. Im Endeffekt sind im gesamten Thread nützliche Informationen zum Thema vorhanden, zu den zwei hier aufgeführten Methoden habe ich die URL in einem Kommentar darüber dazugeschrieben.

Wow!
Besten Dank für die Erklärungen!
Gruß
Wolfgang