Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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!

share|improve this question
    
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? –  tiffon Jan 1 '13 at 0:04
    
@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! –  Badaboooooom Jan 1 '13 at 0:52

1 Answer 1

up vote 3 down vote accepted
+100

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>​
share|improve this answer
    
great, i can't understand why render: option doesn't works then :P –  Badaboooooom Jan 3 '13 at 13:27
    
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 –  RTOSkit Jan 3 '13 at 16:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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