/*
    $Revision$
    $Id$

    File:           date.js

    Description:    Datum gerelateerde functies
*/

// Voor serverside gebruik staan ze ook nog een keer in Shared\locale.inc
var calendar_names = {
      'NL' : {
			days: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag", "zondag"],
			daysShort: ["Zon", "Maa", "Din", "Woe", "Don", "Vri", "Zat", "Zon"],
			daysMin: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo"],
			months: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"],
			monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"],
			weekMin: 'wk'
		   },
      'EN': {
			days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
			daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
			daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
			months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
			monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
			weekMin: 'wk'
		   },
      'DE' : {
			days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"],
			daysShort: ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam", "Son"],
			daysMin: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"],
			months: ["Januar", "Februar", "M&auml;rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
			monthsShort: ["Jan", "Feb", "M&auml;r", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"],
			weekMin: 'wo'
		   },
       'FR' : {
			days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche"],
			daysShort: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"],
			daysMin: ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa", "Di"],
			months: ["janvier", "f&eacute;vrier", "mars", "avril", "mai", "juin", "juillet", "ao&ucirc;t", "septembre", "octobre", "novembre", "d&eacute;cembre"],
			monthsShort: ["Jan", "F&eacute;v", "Mar", "Avr", "Mai", "Jun", "Jul", "Ao&ucirc;", "Sep", "Oct", "Nov", "D&eacute;c"],
			weekMin: "se"
		  },
      'NO' : {
			days: ["s&oslash;ndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "l&oslash;rdag", "s&oslash;ndag"],
			daysShort: ["s&oslash;n", "man", "tir", "ons", "tor", "fre", "l&oslash;r", "s&oslash;n"],
			daysMin: ["s&oslash;", "ma", "ti", "on", "to", "fe", "l&oslash;", "s&oslash;"],
			months: ["januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember"],
			monthsShort: ["jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "dec"],
			weekMin: "uk"
		  },
      'SV' : {
			days: ["s&ouml;ndag", "m&aring;ndag", "tisdag", "onsdag", "torsdag", "fredag", "l&ouml;rdag", "s&ouml;ndag"],
			daysShort: ["s&ouml;n", "m&aring;n", "tis", "ons", "tor", "fre", "l&ouml;r", "s&ouml;n"],
			daysMin: ["s&ouml;", "m&aring;", "ti", "on", "to", "fe", "l&ouml;", "s&ouml;"],
			months: ["januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december"],
			monthsShort: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"],
			weekMin: "vk"
		  },
      'DA' : {
			days: ["s&oslash;ndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "l&oslash;rdag", "s&oslash;ndag"],
			daysShort: ["s&oslash;n", "man", "tir", "ons", "tor", "fre", "l&oslash;r", "s&oslash;n"],
			daysMin: ["s&oslash;", "ma", "ti", "on", "to", "fe", "l&oslash;", "s&oslash;"],
			months: ["januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "desember"],
			monthsShort: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"],
			weekMin: "ug"
		  },
      'FI' : {
			days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai", "sunnuntai"],
			daysShort: ["sun", "maa", "tii", "kes", "tor", "per", "lau", "sun"],
			daysMin: ["su", "ma", "ti", "ke", "to", "pe", "la", "su"],
			months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kes&auml;kuu", "hein&auml;kuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"],
			monthsShort: ["tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mar", "jou"],
			weekMin: "vi"
		  }
}[user_lang];


Date.prototype.midnight = function midnight()
{
    var midn = new Date(this);
    midn.setHours(0);
    midn.setMinutes(0);
    midn.setSeconds(0);
    return midn;
}

function weeksInYear(year) {
  var X1, X2, NW
  with (X1=new Date(year,  0,  4)) setDate(getDate() - (6+getDay())%7) // first day of week 1
  with (X2=new Date(year, 11, 28)) setDate(getDate() + (7-getDay())%7) // last day of week NW
  NW = Math.round((X2-X1)/(7*864e5)) // number of weeks in year
  return NW;
}

function getWnDow(d) { // ISO 8601 WkNo. m=1..12
  if (!d) d = new Date();
  var ms1d = 864e5; // milliseconds one day
  var ms7d = 7*ms1d; // miliseconds 7 days
  var DC3 = Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()+3)/ms1d; // An absolute day number
  var dayofweek = 1 + (DC3+7777777)%7; // Day of Week
  var AWN = Math.floor(DC3/7); // An absolute week number
  var Wyr = new Date(AWN*ms7d).getUTCFullYear();
  var weeknr = AWN - Math.floor(Date.UTC(Wyr, 0, 0)/ms7d);
  return [weeknr, dayofweek ]
}

function getWeeknumber(d) {
  return getWnDow(d)[0];
}

function getDayOfWeek(d) {
  return getWnDow(d)[1];
}

function YWDtoDate(Y, W, D) { // ISO 8601
  var d = new Date(Y, 0, 3)
  d.setDate( 3 - d.getDay() + (W-1) * 7 + D )
  return d
}

function padout(number) { return (number < 10) ? '0' + number : number; }
// This function should only be used to format display,
// – never as part of a computation.
function toTimeString(jsDate, bWithSeconds)
{
    jsDate = new Date(jsDate.valueOf()+1); // rounding errors
    ret = padout(jsDate.getHours())+":"+padout(jsDate.getMinutes());
    if (bWithSeconds) ret += ":"+padout(jsDate.getSeconds());
    return ret;
}
function toDateString(jsDate)
{
    return calendar_names.daysMin[jsDate.getDay()] + " " +
           padout(jsDate.getDate())+"-"+padout(jsDate.getMonth()+1)+"-"+padout(jsDate.getFullYear())
}
function toDateTimeString(jsDate, bWithSeconds)
{
    return toDateString(jsDate)+" "+toTimeString(jsDate, bWithSeconds)
}

Date.prototype.getFloatHours = function getFloatHours()
{
    return this.getHours() + (this.getMinutes()/60);
}
// Noot: rondt af op res_h!
//       levert een nieuw date-object op
Date.prototype.setFloatHours = function setFloatHours(hrs, res_h)
{
    var dd = new Date(this);
    hrs = Math.floor((hrs/res_h)+0.5) * res_h;
    var hh = Math.floor(hrs);
    var mm = (hrs*60) % 60;
    dd.setHours(hh,mm,0,0);
    return dd;
}
// Noot: rondt af op res_h!
//       levert een nieuw date-object op
Date.prototype.addFloatHours = function addFloatHours(hrs, res_h)
{
    return this.setFloatHours(this.getFloatHours() + hrs, res_h);
}

function cal_checkVolgnr(fieldId, volgnr)
{
  // Aangeroepen door de onChange van elke kalender om de volgorde in tijd van de kalenders te controleren
  // Alleen kalenders die een volgnummer hebben gekregen moeten worden gecontroleerd
  // calArray staat nu altijd op volgorde van volgnummer.

  // Controleer of kalender Kx niet na kalender Kx+1, Kx+2... komt. Toch het geval dan Kx+1, Kx+2... = Kx.
  // Controleer of kalender Kx niet voor kalender Kx-1, Kx-2... komt. Toch het geval dan Kx-1, Kx-2... = Kx.
  for (var i = 0; i < calArray.length; i++)
  {
    var fromdate = new Date(parseInt($("#" + fieldId).val())); // degene die de gebruiker net heeft gewijzigd
    // Als de gewijzigde kalender of de vergelijkende kalender een tijdsveld heeft dan ingevulde tijd ook meenemen. Anders 0 nemen.
    // Elke vergelijkende kalender vergelijken met de gewijzigde kalender.
    // Bij lege waarde is $("#time_from_" + XXX).timePickerGetTime() nul(0) en heeft als object dan geen getTime() functie.
    var timefromms = $("#time_from_" + fieldId).length > 0 && $("#time_from_" + fieldId).timePickerGetTime() > 0? $("#time_from_" + fieldId).timePickerGetTime().getTime() : 0; // Gewijzigd veld.
    var timetoms = $("#time_from_" + calArray[i].id).length > 0 && $("#time_from_" + calArray[i].id).timePickerGetTime() > 0? $("#time_from_" + calArray[i].id).timePickerGetTime().getTime() : 0; // Vergelijkend veld.

    // Kalender Kx vooruit gezet
    if (calArray[i].id != fieldId && calArray[i].volgnr > volgnr &&
        ($("#" + calArray[i].id).val() != "") &&
        parseInt($("#" + calArray[i].id).val()) < parseInt($("#" + fieldId).val()))
    { // Veld aanpassen (Veld is ingevuld)
      // Maak Kx+1, Kx+2... gelijk aan Kx
      $("#show_" + calArray[i].id).datepicker('setDate', fromdate);
      $("#show_" + calArray[i].id).val($("#show_" + fieldId).val());

      // Is tijdveld wel aanwezig en is die niet leeg?
      if (timefromms > 0)
      {
        // Als de tijd van tx > tijd van tx+1, tx+2..., maak dan de tijden gelijk: tijd van tx+1, tx+2... = tijd van tx.
        if (timefromms > timetoms)
        { // Datum + tijd overnemen
          $("#" + calArray[i].id).val(fromdate.getTime()); // hidden timestamp
          $("#time_from_" + calArray[i].id).val($("#time_from_" + fieldId).val()); // Zichtbare tijd overnemen
        }
        else
        { // Datum overnemen, eigen tijd behouden
          var dt2 = fromdate.midnight();
          dt2.setSeconds(timetoms / 1000); // setSeconds gaat goed om met zomertijd/wintertijd
          $("#" + calArray[i].id).val(dt2.getTime());
        }
      }
      else
      { // Kalender Kx heeft geen tijdsveld.
        // Indien veld Kx+i wel een tijdsveld heeft, dan eigen tijd behouden.
        var value = fromdate.midnight().getTime()
                  + ($("#time_from_" + calArray[i].id).length > 0 && $("#time_from_" + calArray[i].id).val() != "" // Heeft veld Kx+i een tijdsveld en is die niet leeg?
                    ? timetoms                              // Tijdsveld is aanwezig en niet leeg. Dan kan ik met getTime() de tijd ophalen.
                    : 0)                                                                                           // Tijdsveld is niet aanwezig. Dan nemen we voor de tijd 0.
        $("#" + calArray[i].id).val(value);
      }
    }

    // Kalender Kx achteruit gezet
    if (calArray[i].id != fieldId && calArray[i].volgnr < volgnr && ($("#" + calArray[i].id).val() != "") && parseInt($("#" + calArray[i].id).val()) > parseInt($("#" + fieldId).val()))
    { // Veld aanpassen (Veld is ingevuld)
      // Maak Kx-1, Kx-2... gelijk aan Kx
      $("#show_" + calArray[i].id).datepicker('setDate', fromdate);
      $("#show_" + calArray[i].id).val($("#show_" + fieldId).val());

      // Is tijdveld wel aanwezig en is die niet leeg?
      if ($("#time_from_" + fieldId).length > 0 && $("#time_from_" + fieldId).val() != "" &&
          $("#time_from_" + calArray[i].id).length > 0 && $("#time_from_" + calArray[i].id).val() != "")
      {
        // Als de tijd van tx < tijd van tx-1, tx-2..., maak dan de tijden gelijk: tijd van tx-1, tx-2... = tijd van tx.
        if (timefromms < timetoms)
        { // Datum + tijd overnemen
          $("#" + calArray[i].id).val(fromdate.getTime());// hidden timestamp
          $("#time_from_" + calArray[i].id).val($("#time_from_" + fieldId).val()); // Zichtbare tijd overnemen
        }
        else
        { // Datum overnemen, eigen tijd behouden
          var dt2 = fromdate.midnight();
          dt2.setSeconds(timetoms / 1000); // setSeconds gaat goed om met zomertijd/wintertijd
          $("#" + calArray[i].id).val(dt2.getTime());
        }
      }
      else
      { // Kalender Kx heeft geen tijdsveld.
        $("#" + calArray[i].id).val(fromdate.midnight().getTime());
      }
    }
  }

  // Datums van de zichtbare kalenders staan goed maar de tijd kan nog eerder zijn dan voorafgaande
  // (zichtbare) datum (begindatumtijd > einddatumtijd).
  // Daarnaast eventueel de hidden datums/tijden aanpassen.
  // Werkt ook voor meer dan twee kalenders.
  var defaultvolgnr;
  for (var i = 0; i < calArray.length; i++)
  { // Bepaal volgnr van de eerste zichtbare datum.
    if ($("#" + calArray[i].id).closest("tr").css("display") != "none")
    {
      defaultvolgnr = i;
      var defaultdate = new Date(parseInt($("#" + calArray[defaultvolgnr].id).val()));
      break;
    }
  }
  for (var i = 0; i < calArray.length; i++)
  { // Vind de hidden datum velden. Deze moeten wellicht aangepast worden.
    if (defaultvolgnr == i) continue;
    if (($("#show_" + calArray[i].id).css("display") == "none" || $("#" + calArray[i].id).closest("tr").css("display") == "none") &&
        ($("#show_" + calArray[i].id)[0].getAttribute("nofollow") == 0))
    { // Datum is niet zichtbaar
      // Veld aanpassen
      if ($("#" + calArray[defaultvolgnr].id).val() == "")
      { // Zichtbare datumveld is leeg. Maak hidden datumveld ook leeg
        $("#show_" + calArray[i].id).val("");
        $("#" + calArray[i].id).val("");
      }
      else
      { // Maak datum van datumveld i gelijk aan zichtbare datum.
        // Tijd hidden kalender gelijk maken aan eerstvoorafgaande zichtbare kalender. Indien geen eerstvoorafgaande zichtbare kalender aanwezig dan eerstvolgende zichtbare kalender nemen
        $("#show_" + calArray[i].id).datepicker('setDate', defaultdate);
        $("#show_" + calArray[i].id).val($("#show_" + calArray[defaultvolgnr].id).val());

        // Is tijdveld wel aanwezig en is die niet leeg?
        if ($("#time_from_" + calArray[i].id).length > 0 && $("#time_from_" + calArray[i].id).val() != "")
        { // Tijd veld is aanwezig en is gevuld.
          // Als ik de datum gelijk maak maar de tijd niet aanpas, is dan de begindatumtijd < einddatumtijd?

          var new_date_with_own_time = defaultdate.midnight();
          new_date_with_own_time.setSeconds(timetoms/1000);
          if (defaultdate < new_date_with_own_time)
          { // Zichtbare datum is eerder (begindatumtijd < einddatumtijd), dan alleen datum aanpassen en de tijd niet (eigen tijd behouden)
            $("#" + calArray[i].id).val(new_date_with_own_time.getTime());
          }
          else
          { // Zichtbare datum is later (begindatumtijd > einddatumtijd), dan datum en tijd gelijk zetten
            // Datum en tijd gelijk zetten.
            $("#" + calArray[i].id).val(defaultdate.midnight().setSeconds($("#time_from_" + calArray[defaultvolgnr].id).timePickerGetTime().getTime()/1000));
            $("#time_from_" + calArray[i].id).val($("#time_from_" + calArray[defaultvolgnr].id).val());
          }
        }
      }
    }
    else
    { // Datum is zichtbaar of nofollow = 1
      // Datums zijn nu goed maar de tijd kan nog eerder zijn dan zichtbare datum (begindatumtijd > einddatumtijd)
      // Daarnaast moeten beide datums wel een waarde hebben en moet het tijdveld aanwezig zijn
      if (($("#" + calArray[defaultvolgnr].id).val() > $("#" + calArray[i].id).val()) &&
          ($("#" + calArray[defaultvolgnr].id).val() != "" && $("#" + calArray[i].id).val() != "") &&
          ($("#time_from_" + calArray[i].id).length > 0))
      { // Zichtbare datum is eerder (begindatumtijd > einddatumtijd), deze zichtbare datum gelijk maken aan zichtbare datum
        // Tijd veld is aanwezig. Datum en tijd gelijk zetten.
        $("#" + calArray[i].id).val(defaultdate.midnight().getTime() + $("#time_from_" + calArray[defaultvolgnr].id).timePickerGetTime().getTime());
        $("#time_from_" + calArray[i].id).val($("#time_from_" + calArray[defaultvolgnr].id).val());
      }
      if ($("#" + calArray[i].id).val() != "")
      {
        defaultvolgnr = i;// eerstvoorafgaande zichtbare GEVULDE kalender is nu deze
        var defaultdate = new Date(parseInt($("#" + calArray[defaultvolgnr].id).val()));
      }
    }
  }
}

// te gebruiken in combinatie met FCLTCalender
function cal_isVrijeDag(datum)
{
    var nacht = datum.midnight();
    return ($.inArray(nacht.getTime(), mld_vrije_dagen)> -1);
}

// te gebruiken in combinatie met FCLTCalender
function cal_isWeekend(datum)
{
    var dag = datum.getDay();
    return (dag == 0 || dag == 6); // we ondersteunen geen andere weekenden
}

// Als veld door DatePicker is gewijzigd
function cal_onChange(fieldID, params)
{
    // Eventuele bad class verwijderen. Kan ontstaan door met de hand een verkeerde waarde/formaat in te vullen. Met datepicker altijd juiste waarde/formaat.
    $('#show_' + fieldID).removeClass('bad');
    var dt = parseInt($('#'+fieldID).val()); // Er is een datum ingevuld m.b.v. de datepicker
    if ($("#time_from_" + fieldID).length > 0 && $("#time_from_" + fieldID).val() != "")
    { // De tijd bij de datum optellen indien er een tijd is ingevuld
      var dt2 = new Date(dt).midnight();
      var tm = $("#time_from_"+fieldID).timePickerGetTime().getTime();
      dt2.setSeconds(tm / 1000); // setSeconds gaat goed om met zomertijd/wintertijd
      $('#'+fieldID).val(dt2.getTime());
    }
    else if ($("#time_from_" + fieldID).length == 0 && params.volgnr == 2)
    { // Tijdsveld niet aanwezig en het is een einddatum: De tijd van de einddatum op 23:59 zetten.
      var dt2 = new Date(dt).midnight();
      dt2.setHours(23, 59, 59);
      $('#'+fieldID).val(dt2.getTime());
    }

    if (params.volgnr)
    {
      cal_checkVolgnr(fieldID, params.volgnr);
    }
    if (params.onChange) {
      eval(params.onChange, (new Date(parseInt($('#'+fieldID).val()))));
    }
    if (params.onChangeDate) {
      eval(params.onChangeDate, (new Date(parseInt($('#'+fieldID).val()))));
    }
}

// Als veld door intikken is gewijzigd
// zie ook sortable.js voor DATE_RE
function cal_show_onChange(e)
{
    $(this).removeClass('bad');
    // negeer letters (dag) vooraan
    // sta toe 3 -> 3e van huidige maand en 3-2 -> 3 feb huidig jaar
    var DATE_RE = /^[a-zA-Z ]*(\d\d?)[\/\.\- ]?(\d\d?)?[\/\.\- ]?((\d\d)?\d\d)?$/;
    var dttxt = $(this).val();
    var possdate = dttxt.match(DATE_RE);
    if (possdate && possdate.length)  // er moet minstens iets goed zijn
    {
      var pYear, pMonth, pDay;
      if (possdate.length > 2 && possdate[3])
      {
        var yr = parseInt(possdate[3],10);
        if (yr<100) yr += 2000;
        pYear = yr;
      }
      else
        pYear = new Date().getFullYear();
      if (possdate.length > 1 && possdate[2])
      {
        pMonth = parseInt(possdate[2], 10) - 1
      }
      else
        pMonth = new Date().getMonth();
      pDay = parseInt(possdate[1], 10);
      dt = new Date(pYear, pMonth, pDay);
      $(this).datepicker('setDate', dt);
      if ($(this)[0].onSelect)
        $(this)[0].onSelect.apply();
    }
    else
    {
      if ($(this).val() == "") // Lege waarde mag
        $(this).datepicker('setDate'); // Zet de milliseconden datum op een lege waarde
      else
        $(this).addClass('bad');
    }
}

// Als veld door intikken is gewijzigd
function time_show_onChange(showfieldID, fieldID, params)
{
    var zelf = $("#"+showfieldID);
    $("div.time-holder").hide();
    zelf.removeClass('bad');
    // sta toe 14 -> 14:00h
    // sta toe 930 -> 9:30h
    // sta ook allerlei separators toe.
    var TIME_RE = /^(\d*)[\/\.\-\: ]?(\d\d?)?$/;
    var tmtxt = zelf.val();
    posstime = tmtxt.match(TIME_RE);
    if (posstime && posstime.length && !isNaN(parseInt(posstime, 10)))  // er moet minstens iets goed zijn
    {
      var hh = parseInt(posstime, 10);
      mm = 0;
      if (posstime.length > 1 && posstime[2])
      {
        var mm = parseInt(posstime[2],10);
      }
      else // 930 voor 9:30h
        if (hh > 100)
        {
            mm = hh % 100;
            hh = Math.floor(hh / 100);
        }
      hh = hh % 24;
      mm = mm % 60;
      // Opgeschoonde waarde opslaan
       zelf.val(String((hh<10?"0":"")+hh) + ":" + String((mm<10?"0":"")+mm), true);
       if ($('#'+fieldID).val() != "")
       {
         // Bepaal de milliseconden datum inclusief de tijd
         $('#'+fieldID).val(new Date(parseInt($('#'+fieldID).val())).midnight().getTime()
                                                 + $("#"+showfieldID).timePickerGetTime().getTime());
       }
       if (params.volgnr>=0)
       {
          cal_checkVolgnr(fieldID, params.volgnr);
       }
    }
    else
    {
      if (zelf.val() == "") // Lege waarde mag
      {
        if ($('#'+fieldID).val() != "")
        {
          // Neem de tijd niet mee om de milliseconden datum te zetten (Verminder de miliseconden datum met de tijd)
          $('#'+fieldID).val(new Date(parseInt($('#'+fieldID).val())).midnight().getTime());
        }
      }
      else
        zelf.addClass('bad');
    }

    if (params.onChange) {
      eval(params.onChange);
    }
    if (params.onChangeTime) {
      eval(params.onChangeTime);
    }
}