1
\$\begingroup\$

I'm using this simple plugin to show a simple countdown in my pages, what I would like is to keep it more accurate, cause somentimes it seems it isn't accurate.

This is the plugin:

/*
countdown is a simple jquery plugin for countdowns

Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.

@source: http://github.com/rendro/countdown/
@autor: Robert Fleischmann
@version: 1.0.0
*/


(function() {

  (function($) {
    $.countdown = function(el, options) {
      var getDateData,
        _this = this;
      this.el = el;
      this.$el = $(el);
      this.$el.data("countdown", this);
      this.init = function() {
        _this.options = $.extend({}, $.countdown.defaultOptions, options);
        if (_this.options.refresh) {
          _this.interval = setInterval(function() {
            return _this.render();
          }, _this.options.refresh);
        }
        _this.render();
        return _this;
      };
      getDateData = function(endDate) {
        var dateData, diff;
        endDate = Date.parse($.isPlainObject(_this.options.date) ? _this.options.date : new Date(_this.options.date));
        diff = (endDate - Date.parse(new Date)) / 1000;


        if (diff < 0) {
          diff = 0;
          if (_this.interval) {
            _this.stop();
          }
        }
        dateData = {
          years: 0,
          days: 0,
          hours: 0,
          min: 0,
          sec: 0,
          millisec: 0
        };
        if (diff >= (365.25 * 86400)) {
          dateData.years = Math.floor(diff / (365.25 * 86400));
          diff -= dateData.years * 365.25 * 86400;
        }
        if (diff >= 86400) {
          dateData.days = Math.floor(diff / 86400);
          diff -= dateData.days * 86400 ;
        }
        if (diff >= 3600) {
          dateData.hours = Math.floor(diff / 3600);
          diff -= dateData.hours * 3600;
        }
        if (diff >= 60) {
          dateData.min = Math.floor(diff / 60);
          diff -= dateData.min * 60;
        }
        dateData.sec = diff;

        return dateData;
      };
      this.leadingZeros = function(num, length) {
        if (length == null) {
          length = 2;
        }
        num = String(num);
        while (num.length < length) {
          num = "0" + num;
        }
        return num;
      };
      this.update = function(newDate) {
        _this.options.date = newDate;
        return _this;
      };
      this.render = function() {
        _this.options.render.apply(_this, [getDateData(_this.options.date)]);
        return _this;
      };
      this.stop = function() {
        if (_this.interval) {
          clearInterval(_this.interval);
        }
        _this.interval = null;
        return _this;
      };
      this.start = function(refresh) {
        if (refresh == null) {
          refresh = _this.options.refresh || $.countdown.defaultOptions.refresh;
        }
        if (_this.interval) {
          clearInterval(_this.interval);
        }
        _this.render();
        _this.options.refresh = refresh;
        _this.interval = setInterval(function() {
          return _this.render();
        }, _this.options.refresh);
        return _this;
      };
      return this.init();
    };
    $.countdown.defaultOptions = {
      date: "June 7, 2087 15:03:25",
      refresh: 1000,
      render: function(date) {
        _hey_html = "";
        if(date.years > 0){
          _hey_html += '<span class="countdown-years" title="years left">' + date.years + 'year </span>';
        }
        return $(this.el).html(_hey_html+'<span class="countdown-days" title="days left">  ' + date.days + ' </span><span class="countdown-hours" title="hours left"> ' + (this.leadingZeros(date.hours)) + '<small> h </small> </span><span class="countdown-min" title="minutes left">' + (this.leadingZeros(date.min)) + '<small> m </small> </span><span class="countdown-sec" title="seconds left">' + (this.leadingZeros(date.sec)) + '<small> s </small></span>');
      }
    };
    $.fn.countdown = function(options) {
      return $.each(this, function(i, el) {
        var $el;
        $el = $(el);
        if (!$el.data('countdown')) {
          return $el.data('countdown', new $.countdown(el, options));
        }
      });
    };
    return void 0;
  })(jQuery);

}).call(this);

I think there should be some kind of delay when parsing dates in this plugin, dates are PHP generated as Unixtimestamp then I do this:

$(function(){
  $.each($('.countdown'), function() {
    var _element = '.countdown-'+$(this).attr("id");
    var _id = $(this).attr("id");
    if($(_element).length > 0){
      var _datetime = $(_element).attr('data-expiration').toLocaleString();
      var d = new Date(_datetime).getTime();

      var result = new Date(d);
      _datetime = d;
      init_countdown(_id,_element,_datetime);

    }
  });
});

this is the html

<div data-expiration="Jan 01, 2013 20:01:15" id="25" class="span12    countdown label-expiring  countdown-25">

Sometimes it doesn't shows the real dates, it seems is in delay of about 20/30 minutes, and I can't understand why.

Any help appriaciated, thanks!

\$\endgroup\$
2
  • \$\begingroup\$ Can you post values of the data-expiration attribute along with string representations of the corresponding dates that are created in JS for both inaccurate and accurate countdown values? \$\endgroup\$
    – tiffon
    Commented Jan 1, 2013 at 0:04
  • \$\begingroup\$ @tiffon i added the html element where to bind up the plugin, you can try with different data-expiration and you will check that sometimes it is not accurate or maybe never accurated at all, thanks! \$\endgroup\$ Commented Jan 1, 2013 at 0:52

1 Answer 1

3
+100
\$\begingroup\$

I do not quite understand, why in your code had so many passages from date to date?
if your "tag attribute" was already with a correct date format.

I've done some adjustments in the source code, I've tested and I do not see any kind of delay in the source code or in the plugin.

This is the source code and you can test here:


function init_countdown(id,element,datetime,fullmode){
    var endDate = datetime;
    if(!fullmode){
       $(element).countdown({ date: endDate });
    }else{
        $(element).countdown({
          date: endDate,
          render: function(data) {
            var el = $(this.el);
            el.empty()
              .append("<div>" + this.leadingZeros(data.years, 4) + " <span>years</span></div>")
              .append("<div>" + this.leadingZeros(data.days, 3) + " <span>days</span></div>")
              .append("<div>" + this.leadingZeros(data.hours, 2) + " <span>hrs</span></div>")
              .append("<div>" + this.leadingZeros(data.min, 2) + " <span>min</span></div>")
              .append("<div>" + this.leadingZeros(data.sec, 2) + " <span>sec</span></div>");
          }
        });
    }
 }


$(function(){
  var mode=1;
  $.each($('.countdown'), function() {
    var _element = '.countdown-'+$(this).attr("id");
    var _id = $(this).attr("id");
    if($(_element).length > 0){
      var _datetime = $(_element).attr('data-expiration');
      init_countdown(_id,_element,_datetime,(mode^=1));
    }
  });
});

HTML:

  <body>
      <div id="25" class="span12 countdown label-expiring countdown-25" data-expiration="Jan 01, 2014 20:01:15">
      </div>
      <hr />
      <div id="26" class="span12 countdown label-expiring countdown-26" data-expiration="Jan 01, 2015 20:01:15">
      </div>
      <hr />      
       <div id="27" class="span12 countdown label-expiring countdown-27" data-expiration="Jan 01, 2016 20:01:15">
      </div>
  </body>​
\$\endgroup\$
2
  • \$\begingroup\$ great, i can't understand why render: option doesn't works then :P \$\endgroup\$ Commented Jan 3, 2013 at 13:27
  • \$\begingroup\$ In the example that I have posted, if you see the "init_countdown" there is a parameter called "fullmode" this mode allows working with the render, here you can see the example with the three timers in complete form, and in the other example may you see a mixed mode. I hope I have been helpful \$\endgroup\$
    – RTOSkit
    Commented Jan 3, 2013 at 16:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.