      js_date_days = [
        ["Sun, ", "Mon, ", "Tue, ", "Wed, ", "Thu, ", "Fri, ", "Sat, "],
        ["So, ", "Mo, ", "Di, ", "Mi, ", "Do, ", "Fr, ", "Sa, "],
        ["Dim, ", "Lun, ", "Mar, ", "Mer, ", "Jeu, ", "Ven, ", "Sam, "]
      ];
      js_date_months = [
        [" Jan. ", " Feb. ", " Mar. ", " Apr. ", " May ", " June ", " July ", 
            " Aug. ", " Sept. ", " Oct. ", " Nov. ", " Dec. "],
        [". Jan. ", ". Feb. ", ". Marz ", ". Apr. ", ". Mai ", ". Juni ", ". Juli ", 
            ". Aug. ", ". Sept. ", ". Okt. ", ". Nov. ", ". Dez. "],
        [" janv. ", " févr. ", " mars ", " avril ", " mai ", " juin ", " juil. ",
            " août ", " sept. ", " oct. ", " nov. ", " déc. "]
      ];
      js_date_cet = ["&nbsp;CET", "&nbsp;MEZ", "&nbsp;CET"];
      js_date_cest = ["&nbsp;CEST", "&nbsp;MESZ", "&nbsp;CEST"];
      
      js_date_old_minutes = null;
      
      function setJSDateTime() {
      
        var now = new Date();
      
        // to save some milliseconds, only change seconds, changing the rest only every minute
         
        if (now.getMinutes() != js_date_old_minutes ) {
      
          js_date_old_minutes = now.getMinutes(); // save minute
      
          // we changed minute, refresh the whole txt
          var timeInCH = tS();
          var txt = js_date_days[js_date_lang][timeInCH.getDay()] +
                    timeInCH.getDate() + js_date_months[js_date_lang][timeInCH.getMonth()] +
                    timeInCH.getFullYear() + " " +
                    timeInCH.getHours() + ":" + 
                    lZ(timeInCH.getMinutes()) + ":"; 
          var cet = is_ds() ? js_date_cest[js_date_lang] : js_date_cet[js_date_lang];
      
          document.getElementById("js-date-part1").innerHTML = txt;
          document.getElementById("js-date-cet").innerHTML = cet;
        }
        document.getElementById("js-date-seconds").innerHTML = lZ(now.getSeconds());
      }
      
      // Returns a Date object set to Zurich current wall-time
      function getZurichTime(timeInMillis) {
        var now;
        if (timeInMillis)
          now = new Date(timeInMillis);
        else
          now = new Date();
        var zurichTime = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(),
                                  now.getUTCHours(),now.getUTCMinutes(), now.getUTCSeconds());
        zurichTime.setTime(zurichTime.getTime() + dS() + 3600000);
        return zurichTime;
      }
      
      // Deprecated: use getZurichTime directly.
      function tS() {
        return getZurichTime();
      }
      
      // Tests if we are in DST
      function is_ds() {
        var now = new Date();
        return (
          (now.getTime() > fD(0,2,2,-1).getTime()) &&
          (now.getTime() < fD(0,9,2,-1).getTime())
        );
      }
      
      // Returns 1 hour if DST
      function dS() {
        return is_ds() ? 3600000 : 0;
      }
      
      // Mysterious calculation worthy of a Stonehenge Druid
      function fD(d,m,h,p) {
        var week = (p < 0) ? 7*(p+1) : 7*(p-1),
            nm = (p < 0) ? m+1 : m,
            x = new Date(new Date().getUTCFullYear(), nm, 1 ,h ,0 ,0),
            dOff = 0;
        if (p < 0){
          x.setTime(x.getTime() - 86400000);
        }
        if (x.getDay() != d) {
          dOff = (x.getDay() < d) ? (d - x.getDay()) : 0 - (x.getDay() - d);
          if (p < 0 && dOff > 0) {
            week -= 7;
          }
          if (p > 0 && dOff < 0) {
            week += 7;
          }
          x.setTime(x.getTime() + ((dOff + week) * 86400000));
        }
        return x;
      }
      
      // Put leading 0 on a single digit ("9" -> "09")
      function lZ(x) {
        return (x > 9) ? x: '0' + x;
      }
      
      // Numbers below 500 get 1900 added, e.g. 111 becomes 2011
      function y2(x) {
        x = (x < 500) ? x + 1900 : x;
        return String(x).substring(2,4);
      }

