LastBoyScout: Fehler im Countdownsript

Hallo zusammen,

Mein kleines CountDown- Sript hat bis dato (letztes Jahr) eigentlich immer funktioniert, doch habe ich heute festgestellt, das der Counter um plötzlich um einen Tag zu Früh endet.

Ich kann den Fehler auch nach längerer Suche leider nicht finden, hab ich eventuell Scheuklappen auf?

Kann das auch was mit dem Schaltjahr zu tun haben?

Hoffe jemand kann mir helfen, hier der Code:

[code lang=javascript
function countdown_clock(year, month, day, hour, minute, second, format, timestamp) {
         difference = parseInt(new Date().getTime()) - parseInt(timestamp);
         html_code = '<span id="countdown">counter</span>'; //Container für die Ausgabe
         document.write(html_code);
         countdown(year, month, day, hour, minute, second, format, difference);
         }
function countdown(year, month, day, hour, minute, second, format, difference) {
         if(year > 2000) year = year - 2000;
         Today = new Date();
         Today.setTime(Today.getTime() - difference);
         Todays_Year = Today.getFullYear() - 2000;
         Todays_Month = Today.getMonth() + 1;
         Todays_Date = (new Date(Todays_Year, Todays_Month, Today.getDate(), Today.getHours(), Today.getMinutes(), Today.getSeconds())).getTime();
         Target_Date = (new Date(year, month, day, hour, minute, second)).getTime();
         Time_Left = Math.round((Target_Date - Todays_Date) / 1000);

if(Time_Left < 0) format = '';

switch(format) {
  case 0:
                  //Zeigt Tage, Stunden, Minuten und Sekunden
                    days = Math.floor(Time_Left / (60 * 60 * 24));
                    Time_Left %= (60 * 60 * 24);
                    hours = Math.floor(Time_Left / (60 * 60));
                    Time_Left %= (60 * 60);
                    minutes = Math.floor(Time_Left / 60);
                    Time_Left %= 60;
                    seconds = Time_Left;

dps = ' Tage'; hps = ' Std.'; mps = ' min'; sps = ' s';
                    if(days == 1) dps =' Tag';
                    if(hours == 1) hps =' Std.';
                    if(minutes == 1) mps =' min';
                    if(seconds == 1) sps =' s';

document.getElementById('countdown').innerHTML = 'noch:' + '<br>';
                    document.getElementById('countdown').innerHTML += days + dps + ' ';
                    document.getElementById('countdown').innerHTML += hours + hps + '<br>';
                    document.getElementById('countdown').innerHTML += minutes + mps + ' &amp; ';
                    document.getElementById('countdown').innerHTML += seconds + sps;
                    break;
  case 1:
                  //Dynamisch, blendet null Werte aus
                    dyn = Time_Left;
                    days = Math.floor(Time_Left / (60 * 60 * 24));
                    Time_Left %= (60 * 60 * 24);
                    hours = Math.floor(Time_Left / (60 * 60));
                    Time_Left %= (60 * 60);
                    minutes = Math.floor(Time_Left / 60);
                    Time_Left %= 60;
                    seconds = Time_Left;

dps = ' Tage'; hps = ' Std.'; mps = ' min'; sps = ' s';
                    if(days == 1) dps =' Tag';
                    if(hours == 1) hps =' Std.';
                    if(minutes == 1) mps =' min';
                    if(seconds == 1) sps =' s';

document.getElementById('countdown').innerHTML = 'noch:' + '<br>';
                    if(days > 0) document.getElementById('countdown').innerHTML += days + dps + ' ';
                    if(hours > 0) document.getElementById('countdown').innerHTML += hours + hps + '<br>';
                    if(minutes > 0) document.getElementById('countdown').innerHTML += minutes + mps + ' &amp; ';
                    if(seconds > 0) document.getElementById('countdown').innerHTML += seconds + sps;
                    break;
  case 2:
                  //Dynamisch, zeigt immer nur die größt mögliche Einheit
                    dyn = Time_Left;
                    days = Math.floor(Time_Left / (60 * 60 * 24));
                    Time_Left %= (60 * 60 * 24);
                    hours = Math.floor(Time_Left / (60 * 60));
                    Time_Left %= (60 * 60);
                    minutes = Math.floor(Time_Left / 60);
                    Time_Left %= 60;
                    seconds = Time_Left;

dps = ' Tage'; hps = ' Stdunden'; mps = ' Minuten'; sps = ' Sekunden';
                    if(days == 1) dps =' Tag';
                    if(hours == 1) hps =' Stdunde';
                    if(minutes == 1) mps =' Minute';
                    if(seconds == 1) sps =' Sekunde';

document.getElementById('countdown').innerHTML = 'noch:' + '<br>';
                    if(dyn > 86400) document.getElementById('countdown').innerHTML += days + dps;
                    if(dyn < 86400 && dyn > 3600) document.getElementById('countdown').innerHTML += hours + hps;
                    if(dyn < 3600 && dyn > 60) document.getElementById('countdown').innerHTML += minutes + mps;
                    if(dyn < 60) document.getElementById('countdown').innerHTML += seconds + sps;
                    break;
  default:
                  //Zeigt Ausgabe wenn die Zeit erreicht ist
                    document.getElementById('countdown').innerHTML = '3...2..1.';
               }

setTimeout('countdown(' + year + ',' + month + ',' + day + ',' + hour + ',' + minute + ',' + second + ',' + format + ',' + difference + ');', 1000);
         }
[/code]

  1. Hallo.

    Das Erste, was mir aufgefallen ist: Du hast denselben Codeblock 3 mal in der Switch-Anweisung statt davor. Was für eine Codeverschwendung. Das Zweite, was mir aufgefallen ist: Du könntest durchaus die Modi innerhalb einer Anzeigeroutine verwenden und kommst mit weit weniger Code auf das gleiche Ergebnis. Außerdem kannst Du die Division/Modulo kombinieren, ohne auf Time_left einzuwirken, etwa so:

      
    ... = dateDiff / 86400000 + // days  
    ... +  
          (dateDiff / 3600000) % 24 + // hours  
    ... +  
          (dateDiff / 60000) % 60 + // minutes  
    ... +  
          (dateDiff / 1000) % 60 + // seconds  
    
    

    Zuguterletzt würde ich an Deiner Stelle noch window.setInterval statt Timeout nehmen, aber das ist natürlich Geschmackssache. Was Dein Problem angeht: kann es sein, dass Du den Monat versehentlich doch mit einem Wert mehr oder weniger angegeben hast, um zu korrigieren, was Du in der Zeile "Todays_Month = Today.getMonth() + 1;" bereits ausgeglichen hast?

    Gruß, LX

    --
    X-Self-Code: sh:( fo:) ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: Unusual
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hallo LX,

      Ich hab den Code jetzt mal etwas Kompakter gestaltet, Danke für den Hinweis.
      Das Script habe ich in einer extra Datei countdown.js ausgelagert.
      Es wird von PHP nur bei bedarf eingebunden.
      Die übergebende Werte werden ebenfalls von PHP aus einer Datenbank geholt und übergeben, daher sind diese auch die tatsächlichen Zeiten ohne jegliche Korrektur.
      Auch habe ich extra noch den Timestamp des Server als letzten Parameter mit übergeben um eventuelle Abweichungen der Rechnerzeit der User zu korrigieren.
      Was genau du mit deinen anderen Vorschlägen meinst, ist mir noch nicht so klar (bin etwas unbedarft in Java) und ich würde dich bitte es mir noch etwas zu verdeutlichen (am besten mal einbauen) damit es klarer wird.
      Das mit der Abweichung (unter XP) um einen Tag zu früh, ist auf meinem zweit Rechner (unter W2K) nicht aufgetreten, obwohl Datum und Uhrzeit bei beiden gleich ist, was das Rätsel für mich aber nur noch undurchsichtiger macht!?

      Hier der neue Code:

        
      function countdown_clock(year, month, day, hour, minute, second, format, timestamp) {  
               difference = parseInt(new Date().getTime()) - parseInt(timestamp);  
               html_code = '<span id="countdown">counter</span>'; //Container für die Ausgabe  
               document.write(html_code);  
               countdown(year, month, day, hour, minute, second, format, difference);  
               }  
      function countdown(year, month, day, hour, minute, second, format, difference) {  
               if(year > 2000) year = year - 2000;  
               Today = new Date();  
               Today.setTime(Today.getTime() - difference);  
               Todays_Year = Today.getFullYear() - 2000;  
               Todays_Month = Today.getMonth() + 1;  
               Todays_Date = (new Date(Todays_Year, Todays_Month, Today.getDate(), Today.getHours(), Today.getMinutes(), Today.getSeconds())).getTime();  
               Target_Date = (new Date(year, month, day, hour, minute, second)).getTime();  
               Time_Left = Math.round((Target_Date - Todays_Date) / 1000);  
        
               if(Time_Left < 0) format = '';  
        
         dyn = Time_Left;  
               days = Math.floor(Time_Left / (60 * 60 * 24));  
               Time_Left %= (60 * 60 * 24);  
               hours = Math.floor(Time_Left / (60 * 60));  
               Time_Left %= (60 * 60);  
               minutes = Math.floor(Time_Left / 60);  
               Time_Left %= 60;  
               seconds = Time_Left;  
        
               switch(format) {  
         case 0: //Zeigt Tage, Stunden, Minuten und Sekunden  
                          dps = ' Tage'; hps = ' Std.'; mps = ' min'; sps = ' s';  
                          if(days == 1) dps =' Tag';  
                          if(hours == 1) hps =' Std.';  
                          if(minutes == 1) mps =' min';  
                          if(seconds == 1) sps =' s';  
                          document.getElementById('countdown').innerHTML = 'noch:' + '<br>';  
                          document.getElementById('countdown').innerHTML += days + dps + ' ';  
                          document.getElementById('countdown').innerHTML += hours + hps + '<br>';  
                          document.getElementById('countdown').innerHTML += minutes + mps + ' &amp; ';  
                          document.getElementById('countdown').innerHTML += seconds + sps;  
                   break;  
         case 1: //Dynamisch, blendet null Werte aus  
                          dps = ' Tage'; hps = ' Std.'; mps = ' min'; sps = ' s';  
                          if(days == 1) dps =' Tag';  
                          if(hours == 1) hps =' Std.';  
                          if(minutes == 1) mps =' min';  
                          if(seconds == 1) sps =' s';  
                          document.getElementById('countdown').innerHTML = 'noch:' + '<br>';  
                          if(days > 0) document.getElementById('countdown').innerHTML += days + dps + ' ';  
                          if(hours > 0) document.getElementById('countdown').innerHTML += hours + hps + '<br>';  
                          if(minutes > 0) document.getElementById('countdown').innerHTML += minutes + mps + ' &amp; ';  
                          if(seconds > 0) document.getElementById('countdown').innerHTML += seconds + sps;  
                   break;  
         case 2: //Dynamisch, zeigt immer nur die größt mögliche Einheit  
                          dps = ' Tage'; hps = ' Stdunden'; mps = ' Minuten'; sps = ' Sekunden';  
                          if(days == 1) dps =' Tag';  
                          if(hours == 1) hps =' Stdunde';  
                          if(minutes == 1) mps =' Minute';  
                          if(seconds == 1) sps =' Sekunde';  
                          document.getElementById('countdown').innerHTML = 'noch:' + '<br>';  
                          if(dyn > 86400) document.getElementById('countdown').innerHTML += days + dps;  
                          if(dyn < 86400 && dyn > 3600) document.getElementById('countdown').innerHTML += hours + hps;  
                          if(dyn < 3600 && dyn > 60) document.getElementById('countdown').innerHTML += minutes + mps;  
                          if(dyn < 60) document.getElementById('countdown').innerHTML += seconds + sps;  
                   break;  
         default: //Zeigt Ausgabe wenn die Zeit erreicht ist  
                          document.getElementById('countdown').innerHTML = '3...2..1.';  
              }  
        
               setTimeout('countdown(' + year + ',' + month + ',' + day + ',' + hour + ',' + minute + ',' + second + ',' + format + ',' + difference + ');', 1000);  
      }  
      
      

      Gruß LastBoyScout