3

Good day,

I'm having a little trouble with calculating number of days from now to a selected date after selecting a date from jQuery datepicker.

I think that the datepicker is changing the date formatting of the date on selection and causing the calculation to go wrong but I can't quite figure out how to counter this. I am sure it is me but I can't see the forest for the trees so any suggestions would be really helpful.

Here is the code:

<input type="text" class="datepicker-calc" />
<input type="text" id="tbAddDays" />
$(document).ready(function () {
    $(".datepicker-calc").datepicker({
        dateFormat: "dd/mm/yy",
        changeMonth: true,
        changeYear: true,
        onSelect: function (date, e) {
            var expDate = new Date(date);
            var date = e.selectedDay;
            if (date < 10) {
                date = ("0" + e.selectedDay)
            }
            var month = e.selectedMonth;
            if (month < 10) {
                month = ("0" + e.selectedMonth)
            }
            var year = e.selectedYear;
            var endDate = month + "/" + date + "/" + year;
            updateDays(endDate, e);
            $(".datepicker-calc").datepicker("hide");
        }
    });

    function treatAsUTC(date) {
        var result = new Date(date);
        result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
        return result;
    }

    function updateDays(expDate, e) {
        var now = new Date();
        var startDate = now.toDateString('dd/MM/yyyy');
        var exp = new Date(expDate);
        var endDate = exp.toDateString('dd/MM/yyyy');
        var millisecondsPerDay = 24 * 60 * 60 * 1000;
        var totalDays = (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
        $('#tbAddDays').val(totalDays);
    }
});
badstyle
  • 41
  • 1
  • 7

2 Answers2

2

The onSelect event will receive a string in the specified format, which is dd/mm/yy. JavaScript Date.parse method will parse such dates incorrectly, or not parse them at all. The solution is to use parseDate() function built into jQuery ui:

onSelect: function (dateText, inst) {
  var expDate = $.datepicker.parseDate(inst.settings.dateFormat, dateText, inst.settings);
  var diff = expDate - new Date();
  var days = diff / 1000 / 60 / 60 / 24;
  alert( /* ceil, floor, round */ days);
}
Salman A
  • 262,204
  • 82
  • 430
  • 521
  • thanks for pointing me in the right direction. As I required the date format to display in dd/mm/yyyy within the datepicker field, so I implemented a slice solution on the date and broke it apart into mm/dd/yyyy format to run the calculation on. Solution added to the post. – badstyle Jan 11 '13 at 10:49
  • There is a $.datepicker.formatDate function which does the opposite of parstDate, you will find it useful. – Salman A Jan 11 '13 at 11:07
0

Realised that I need the display to be in jQuery dd/mm/yy (dd/mm/yyyy) format so kept that and did some manipulation to the expDate being passed to the updateDays() method to ensure that the date to be calculated would be handled correctly by JS.

Working script:

$(".datepicker-calc").datepicker({
      dateFormat: "dd/mm/yy",
      changeMonth: true,
      changeYear: true,
      onSelect: function (selectdate, e) {
      var newDate = selectdate.slice(0,2);
      var newMonth = selectdate.slice(4,6);
      if (newMonth < "10") { newMonth = ("0" + newMonth.slice(0,1));};
      var newYear = selectdate.slice(6,11);
      var expDate = newMonth + "/" + newDate + "/" + newYear;
      updateDays(expDate, e);
      $(".datepicker-calc").datepicker("hide");
   }
});

function treatAsUTC(date) {
    var result = new Date(date);
    result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
    return result;
}

function updateDays(expDate, e) {
    var now = new Date();
    var startDate = now.toDateString('dd/MM/yyyy');
    var expire = new Date(expDate);
    var endDate = expire.toDateString('dd/MM/yyyy');
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    var totalDays = (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
    $('#tbAddDays').val(totalDays);
}
badstyle
  • 41
  • 1
  • 7