function WWTime() {

  //----------------------------
  // Zeitzonen
  //----------------------------

  /*
  Chile Daylight Saving Time:  GMT-3 //   Begins on 1st Sunday on or after 9 October
  Chile Standard Time: GMT-4         //   Begins on 1st Sunday on or after 9 March
  Sommerzeit USA und Kanada ab 2007: 2. Sonntag im März 2->3 Uhr / 1. So im November 2->1 Uhr
  */

  var iTz    =  0;
  var iTs    =  1;
  var iDvr   =  2;
  var iDmon  =  3;
  var iDtag  =  4;
  var iDwtag =  5;
  var iDzeit =  6;
  var iSvr   =  7;
  var iSmon  =  8;
  var iStag  =  9;
  var iSwtag = 10;
  var iSzeit = 11;
  var zmc = 'dt';

  this.Zeitzone = new Array();
  // Startangaben Sommer-/Winterzeit: vorwärts/rückwärts suchen ab Monat/Tag nach Wochentag, Uhrzeit nach Umschaltung
  //                                  ts  Sommerzeit                     Standardzeit
  //                            iTz     iTs  iDvr iDmon iDtag iDwtag iDzeit iSvr iSmon iStag iSwtag iSzeit
  //this.Zeitzone["NZST"]  = new Array("NZST",  12,   1,  10,    1,    0,     3,     1,   3,   15,    0,     2); // Neuseeland (bis 2007)
  this.Zeitzone["NZST"]  = new Array("NZST",  12,  -1,   9,   30,    0,     2,     1,   4,    1,    0,     3); // Neuseeland (iSzeit ist genaugenommen 2:45)
  this.Zeitzone["AEST"]  = new Array("AEST",  10,   0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // keine Sommerzeit (Queensland / Australien)
  this.Zeitzone["ACST"]  = new Array("ACST",   9.5, 0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // keine Sommerzeit (Darwin / Australien)
  this.Zeitzone["JST"]   = new Array("JST",    9,   0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // keine Sommerzeit (Japan)
  this.Zeitzone["CST"]   = new Array("CST",    8,   0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // keine Sommerzeit (China, hat nur eine
                                                                                                               // Zeitzone!)
  this.Zeitzone["CAT"]   = new Array("CAT",    2,   0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // keine Sommerzeit (Botswana)
  this.Zeitzone["SAST"]  = new Array("SAST",   2,   0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // keine Sommerzeit (Südafrika)
  this.Zeitzone["EET"]   = new Array("EET",    2,  -1,   3,   31,    0,     4,    -1,  10,   31,    0,     3); // Estland, Finnland, Lettland, Litauen,
                                                                                                               // Rumänien, Weißrussland
  this.Zeitzone["UTC"]   = new Array("UTC",    0,  -1,   3,   31,    0,     2,    -1,  10,   31,    0,     1); // Großbritannien
  this.Zeitzone["CET"]   = new Array("CET",    1,  -1,   3,   31,    0,     3,    -1,  10,   31,    0,     2); // Mitteleuropa
  this.Zeitzone["ROTT"]  = new Array("ROTT",  -3,   0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // keine Sommerzeit (South Georgia / Antarktis)
  this.Zeitzone["BRST"]  = new Array("BRST",  -3,   1,  10,   15,    0,     1,     1,   2,   15,    0,    23); // Brasilien (Süden, Südosten und Mittelwesten)
  this.Zeitzone["CLST"]  = new Array("CLST",  -4,   1,  10,    9,    0,     1,     1,   3,    9,    0,    23); // Chile, GARS O'Higgins / Antarktis
  this.Zeitzone["AST"]   = new Array("AST",   -4,   1,   3,    8,    0,     3,     1,  11,    1,    0,     1); // Kanada (Nova Scotia)
  this.Zeitzone["ECT"]   = new Array("ECT",   -5,   0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // keine Sommerzeit (Ecuador)
  this.Zeitzone["USEST"] = new Array("USEST", -5,   1,   3,    8,    0,     3,     1,  11,    1,    0,     1); // USA, Kanada
  this.Zeitzone["USCST"] = new Array("USCST", -6,   1,   3,    8,    0,     3,     1,  11,    1,    0,     1); // USA, Kanada
  this.Zeitzone["BECST"] = new Array("BECST", -6,   0,   0,    0,    0,     0,     0,   0,    0,    0,     0); // Belize
  this.Zeitzone["USMST"] = new Array("USMST", -7,   1,   3,    8,    0,     3,     1,  11,    1,    0,     1); // USA, Kanada
  this.Zeitzone["USPST"] = new Array("USPST", -8,   1,   3,    8,    0,     3,     1,  11,    1,    0,     1); // USA, Kanada
  this.Zeitzone["AKST"]  = new Array("AKST",  -9,   1,   3,    8,    0,     3,     1,  11,    1,    0,     1); // USA (Alaska)

  // Brasilien: Die Sommerzeit ist seit 2009 einheitlich geregelt und betrifft die Bundesstaaten im Süden, Südosten und Mittelwesten: Rio Grande do Sul, Santa Catarina,
  //            Paraná, São Paulo, Rio de Janeiro, Espírito Santo, Minas Gerais, Goiás, Mato Grosso, Mato Grosso do Sul sowie den Hauptstadtdistrikt Brasília.
  //            Die Sommerzeit beginnt um Mitternacht des dritten Sonntags im Oktober und dauert bis um Mitternacht des dritten Sonntags im Februar.
  //            Fällt das Ende der Sommerzeit auf einen Karnevalssonntag, wird die Uhr erst eine Woche später wieder zurückgestellt.

  // Israel hat keine feste Regel für den Termin zur Umstellung auf Sommerzeit/Standardzeit - der Einfachheit halber wie EET behandeln

  var offset = new Array();

  //----------------------------
  // Test Zeitzonenanzeige
  //----------------------------
  function ShowTimeTest(tz) {
    var ztext;
    if (this.Zeitzone[tz][iTs] > 0) {
      ztext = '<br>UTC+' + this.Zeitzone[tz][iTs];
    } else {
      ztext = '<br>UTC'  + this.Zeitzone[tz][iTs];
    }
    return ztext;
  }

  //----------------------------
  // Uhrzeit für InfoWindow
  //----------------------------
  var msecHour = 60 * 60 * 1000; // in Millisekunden
  var msecUTC = 0;

  var Monate;
  var WTage;

  if (wwLang.language == "de") {
    Monate = new Array("Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez");
    WTage  = new Array("So","Mo","Di","Mi","Do","Fr","Sa");
  } else {
    Monate = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
    WTage  = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
  }

  this.Uhrzeit = function(tz) {
    if (!this.Zeitzone[tz]) {
      if (window.location.hostname == "localhost") {  // Meldung nur lokal
        alert("Error timezone: " + tz);
      }
      return ("");
    }

    var ztext = "";
    var timeUTC   = new Date();
    msecUTC   = Date.parse(timeUTC.toGMTString()) // Millisekunden seit dem 01.01.1970
              + wwParam.msecDiff;
    var msecLocal = msecUTC + this.Zeitzone[tz][iTs] * msecHour;

    var textSz = "";
    var bSz = this.Sommerzeit(msecLocal, tz);
    if (bSz == 1) {
      msecLocal += bSz * msecHour;
      if (wwLang.language == "de") {
        textSz = " (S)";
      } else {
        textSz = " (DST)";
      }
    }

    return (this.UhrzeitHtml(msecLocal, forInfoWindow, textSz));
  }

  //----------------------------
  // Uhrzeit HTML generieren
  //----------------------------
  var  forInfoWindow  = 1;
  var  forTime        = 2;
  var  forTimeShort   = 3;
  this.forSaSuShort   = 4;
  this.forSaSuLong    = 5;
  this.forSaSuDayOnly = 6;

  this.UhrzeitHtml = function(msec, format, textSz) {
    var zeit = new Date(msec);

    var wday    = zeit.getUTCDay();
    var year    = zeit.getUTCFullYear();
    var month   = zeit.getUTCMonth();
    var day     = zeit.getUTCDate();
    var hours   = zeit.getUTCHours();
    var minutes = zeit.getUTCMinutes();
    var seconds = zeit.getUTCSeconds();

    //month   = ((month   < 10) ? "0" + month   : month);
    day     = ((day     < 10) ? "0" + day     : day);
    minutes = ((minutes < 10) ? "0" + minutes : minutes);
    seconds = ((seconds < 10) ? "0" + seconds : seconds);

    if (wwLang.language == "de") {
      hours  = ((hours   < 10) ? "0" + hours   : hours);
      month += 1; // da Zählung bei 0 beginnt
      month  = ((month   < 10) ? "0" + month   : month);
      if (format == forInfoWindow) {
        ztext = WTage[wday] + ', ' + ' ' + day + '.' + month + '.' + year + ' ' + hours + ':' + minutes + textSz;
      } else if (format == this.forSaSuShort) {
        ztext = day + '.' + month + '.'        + ' ' + hours + ':' + minutes;
      } else if (format == this.forSaSuLong) {
        ztext = day + '.' + month + '.' + year + ' ' + hours + ':' + minutes;
      } else if (format == this.forSaSuDayOnly) {
        ztext = day + '.' + month + '.' + year;
      } else if (format == forTimeShort) {
        ztext = hours + ':' + minutes;
      } else { // nur Uhrzeit, aktualisierend
        ztext = hours + ':' + minutes + ':' + seconds;
      }
    } else {
      var ampm;
      if (hours >= 12) {
        ampm = "pm";
      } else {
        ampm = "am";
      }
      if (hours >= 13) {
        hours -= 12;
      }
      if (format == forInfoWindow) {
        ztext = WTage[wday] + ' ' + Monate[month] + ' ' + day + ', ' + year + ' ' + hours + ':' + minutes + ' ' + ampm + textSz;
      } else if (format == this.forSaSuShort) {
        ztext = Monate[month] + ' ' + day + ', '        + ' ' + hours + ':' + minutes + ' ' + ampm;
      } else if (format == this.forSaSuLong) {
        ztext = Monate[month] + ' ' + day + ', ' + year + ' ' + hours + ':' + minutes + ' ' + ampm;
      } else if (format == this.forSaSuDayOnly) {
        ztext = Monate[month] + ' ' + day + ', ' + year;
      } else if (format == forTimeShort) {
        ztext = hours + ':' + minutes + ' ' + ampm;
      } else { // nur Uhrzeit, aktualisierend
        ztext = hours + ':' + minutes + ':' + seconds + ' ' + ampm;
      }
    }
    return ztext;
  }

  //----------------------------
  // auf Sommerzeit prüfen
  //----------------------------
  // Wochentage: 0 = Sonntag,..., 6 = Samstag
  this.Sommerzeit = function(msecLocal, tz) {
    startD = new Date(msecUTC);
    startD.setUTCMonth(this.Zeitzone[tz][iDmon] - 1);
    startD.setUTCDate(this.Zeitzone[tz][iDtag]);
    startD.setUTCHours(this.Zeitzone[tz][iDzeit]);
    startD.setUTCMinutes(0);
    startD.setUTCSeconds(0);
    var wtagDD = startD.getDay();
    var wtagD  = this.Zeitzone[tz][iDwtag];
    var diff = wtagD - wtagDD;
    if (this.Zeitzone[tz][iDvr] == -1) {
      if (diff > 0) {
        diff -= 7;
      }
    }
    if (this.Zeitzone[tz][iDvr] == 1) {
      if (diff < 0) {
        diff += 7;
      }
    }
    var msecStartD = Date.parse(startD.toGMTString()); // Millisekunden seit dem 01.01.1970
    msecStartD += diff * msecHour * 24; // Anzahl Tage, um auf den richtigen Wochentag (üblicherweise Sonntag) zu kommen

    startS = new Date(msecUTC);
    startS.setUTCMonth(this.Zeitzone[tz][iSmon] - 1);
    startS.setUTCDate(this.Zeitzone[tz][iStag]);
    startS.setUTCHours(this.Zeitzone[tz][iSzeit]);
    startS.setUTCMinutes(0);
    startS.setUTCSeconds(0);
    var wtagSS = startS.getDay();
    var wtagS  = this.Zeitzone[tz][iDwtag];
    var diff = wtagS - wtagSS;
    if (this.Zeitzone[tz][iSvr] == -1) {
      if (diff > 0) {
        diff -= 7;
      }
    }
    if (this.Zeitzone[tz][iSvr] == 1) {
      if (diff < 0) {
        diff += 7;
      }
    }
    var msecStartS = Date.parse(startS.toGMTString()); // Millisekunden seit dem 01.01.1970
    msecStartS += diff * msecHour * 24; // Anzahl Tage, um auf den richtigen Wochentag (üblicherweise Sonntag) zu kommen

    var bIsSz = 0;
    if (msecStartD < msecStartS) {
      msecStartD -= msecHour; // umrechnen auf Zeit vor der Umstellung auf Sommerzeit
      if ((msecLocal >= msecStartD) && (msecLocal < msecStartS)) {
        // Sommerzeit
        bIsSz = 1;
      }
    }
    if (msecStartS < msecStartD) {
      msecStartD -= msecHour; // umrechnen auf Zeit vor der Umstellung auf Sommerzeit
      if ((msecLocal < msecStartS) || (msecLocal >= msecStartD)) {
        // Sommerzeit
        bIsSz = 1;
      }
    }
    return bIsSz;
  }

  //----------------------------
  // Anzeige aktuelle Zeit
  //----------------------------
  // Initialisierung der Farben mit provisorischen Werten, wird beim ersten getSunRiseSet() richtig gesetzt:
  this.colTxtUhr    = '#F8F8F8';
  this.colBgUhr     = '#F8F8F8';
  this.UhrzeitAktuell = function() {
    var jetzt   = new Date();
    var msecNow = jetzt.getTime();
    var tsMinutes = - jetzt.getTimezoneOffset(); // in Minuten (GMT minus Ortszeit)
    var ts = tsMinutes * 60 * 1000 + wwParam.msecDiff;

    var strImg = "";
    $("Uhr").innerHTML  = '<nobr><span style="background-color:'
                                              + this.colBgUhr   + ';color:' + this.colTxtUhr
                                              + ';border-width:3px; border-color:' + this.colTxtUhr
                                              + '; border-style:double; cursor:pointer;">'
                                              + '&nbsp;&nbsp;'
                                              + this.UhrzeitHtml(msecNow + ts, forTime, "")
                                              + '&nbsp;&nbsp;</span>' + strImg + '</nobr>';
    wwSun.SetSunRiseSetHtml(); // Sonnenauf-/untergangszeiten aktualisieren, falls nötig
  }

  //----------------------------
  // automatische Aktualisierung
  //----------------------------
  this.actualizeTime = null;
  this.SetUhrzeitAktuell = function() {
    if (!wwParam.bShowSunRiseSet) {
      return;
    }
    if (this.actualizeTime) {
      window.clearInterval(this.actualizeTime);
    }
    this.UhrzeitAktuell();
    this.actualizeTime = window.setInterval("wwTime.UhrzeitAktuell()", 1000);
  }

}

var wwTime = new WWTime();

