Javascript & JQuery - Weird new Date() Issue
I'm using Keith Wood's jQuery datepicker http://keith-wood.name/datepick.html to make a calendar that the user can use to switch between a range of dates or selecting individual dates. The site itself can be viewed at http://www.hasslers.org.
The calendar works well as is, but it has a problem with computing the cost of the range of days. The way the code works is it takes a string from the datepicker representing the two dates and breaks them into separate strings. From there, the string information is converted into seperate variables representing the day, month, and year.
The variables all show the proper values when I use an alert window to pop them up. I can select almost any beginning day and have the script work perfectly; however, when I select the current day or the day after the new date variable sets itself to October 1st. This only happens with days near the current day.
Enough of my rambling, here is the section of the code that seems to be the troublemaker:
var dates_string = datepicker_data.toString();
var dates = dates_string.split(',');
var day1 = dates[0].slice(8, 10);
var day2 = dates[1].slice(8, 10);
var month1 = dates[0].slice(4, 7);
var month2 = dates[1].slice(4, 7);
switch(month1) {
case "Jan":
month1 = 0;
break;
case "Feb":
month1 = 1;
break;
case "Mar":
month1 = 2;
break;
case "Aprl":
month1 = 3;
break;
case "May":
month1 = 4;
break;
case "Jun":
month1 = 5;
break;
case "Jul":
month1 = 6;
break;
case "Aug":
month1 = 7;
break;
case "Sep":
month1 = 8;
break;
case "Oct":
month1 = 9;
break;
case "Nov":
month1 = 10;
break;
case "Dec":
month1 = 11;
break;
}
switch(month2) {
case "Jan":
month2 = 0;
break;
case "Feb":
month2 = 1;
break;
case "Mar":
month2 = 2;
break;
case "Aprl":
month2 = 3;
break;
case "May":
month2 = 4;
break;
case "Jun":
month2 = 5;
break;
开发者_Python百科 case "Jul":
month2 = 6;
break;
case "Aug":
month2 = 7;
break;
case "Sep":
month2 = 8;
break;
case "Oct":
month2 = 9;
break;
case "Nov":
month2 = 10;
break;
case "Dec":
month2 = 11;
break;
}
var year1 = dates[0].slice(11, 15);
var year2 = dates[1].slice(11, 15);
var split_date1 = new Date();
var split_date2 = new Date();
split_date1.setDate(parseInt(day1));
split_date2.setDate(parseInt(day2));
split_date1.setMonth(month1);
split_date2.setMonth(month2);
split_date1.setYear(parseInt(year1));
split_date2.setYear(parseInt(year2));
// get number of days by dividing by 86400000 milliseconds (number in a day)
number_of_days = ((split_date2 - split_date1) / 86400000) + 1;
You're using two digits for the day of the month:
var day1 = dates[0].slice(8, 10);
var day2 = dates[1].slice(8, 10);
I don't know what format your dates are in but if the eighth is represented as 08
then you're in trouble. The parseInt
function has a second argument that specifies the base of the number; if you don't specify the radix then parseInt
will have to guess and if you give it a number that begins with a zero, it will guess octal. The result is that parseInt('08')
will result in zero because 8
is not a valid octal digit. You should always specify the radix when using parseInt
.
Today is conveniently the 8th so let us look what happens.
var d = new Date();
// Thu Sep 08 2011 20:12:43 GMT-0700 (PDT)
d.setDate(parseInt('08'));
d.toString();
// "Wed Aug 31 2011 20:12:43 GMT-0700 (PDT)"
And so we lose some time while attempting to set the date to the 8th and everything goes sideways after that.
I'm not sure if this is your specific problem but it is a nasty problem that needs to be fixed.
Perhaps the author gets paid by the yard, e.g. to convert a 3 letter month abbreviation to a number for a JS date:
function convertMonthToNumber(mon) {
var months = {jan:0, feb:1, mar:2, apr:3, may:4, jun:5,
jul:6, aug:7, sep:8, oct:9, nov:10, dec:11};
return months[mon.toLowerCase()];
}
replaces over 70 lines of the above code.
If you post the format of the date strings, a "difference in days" can be provided very simply. It should probably not just divide by 8.64e7 as daylight saving may interfere. Anyway, it seems that your issue with the input date, not the actual calculation.
The following function will return the difference in days given two date objects.
function getDaysBetweenDates(d0, d1) {
var msPerDay = 8.64e7;
// Copy dates so don't mess them up
var x0 = new Date(d0);
var x1 = new Date(d1);
// Set to noon - avoid time errors
x0.setHours(12,0,0);
x1.setHours(12,0,0);
// Round to remove daylight saving errors
return Math.round( (x1 - x0) / msPerDay );
}
精彩评论