Javascript和JQuery - 新的Date()问题奇怪

3
我正在使用Keith Wood的jQuery日期选择器http://keith-wood.name/datepick.html制作一个日历,用户可以用它在一系列日期之间切换或选择单个日期。网站本身可以在http://www.hasslers.org上查看。
日历本身运行良好,但计算日期范围的成本时存在问题。代码的工作方式是从日期选择器中获取表示两个日期的字符串并将其拆分为单独的字符串。然后,将字符串信息转换为表示天、月和年的单独变量。
当我使用警告窗口弹出它们时,所有变量都显示正确的值。我可以选择几乎任何一个开始日期,并且脚本可以完美地工作;然而,当我选择当前日期或后一天时,新日期变量会将自己设置为10月1日。这只发生在靠近当前日期的日期。
足够我的唠叨不提了,这里是似乎是麻烦制造者的代码部分:
    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;
        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;

2个回答

4
也许作者按字数计费,例如将JS日期中的3个字母的月份缩写转换为数字:
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()];
}

替换了上面代码中超过70行的内容。

如果您发布日期字符串的格式,"天数差"可以非常简单地提供。它可能不仅仅是通过8.64e7除以来解决的,因为夏令时可能会干扰。无论如何,似乎您的问题在于输入日期,而不是实际计算。

以下函数将返回给定两个日期对象之间的天数差。

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 );
}

感谢提供这个简化函数,它将在我的代码中节省大量空间。我不知道你可以用那种风格来编写类似于switch的语句。我有一种感觉我一直在以非常懒惰的方式编写代码。 - Yokel Pole

4

您正在使用月份日期的两个数字:

var day1 = dates[0].slice(8, 10);
var day2 = dates[1].slice(8, 10);

我不知道你的日期格式是什么,但如果“八日”用08表示,那么就会有问题。 parseInt函数有第二个参数指定数字的基数;如果你不指定基数,那么parseInt将会猜测,而如果你给它一个以零开头的数字,它将会猜测为八进制。结果是parseInt('08')将得到零,因为8不是有效的八进制数字。 当使用parseInt时,你应该总是指定基数。
今天恰好是8日,让我们看看会发生什么。
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)"

在尝试将日期设置为8号时,我们浪费了一些时间,并且之后情况变得非常糟糕。

我不确定这是否是您遇到的特定问题,但这是一个需要解决的麻烦问题。


这完全解决了我的问题!当我在月末设计页面时,这绝对是一个让我忽视的麻烦问题。 - Yokel Pole
@user683946:真正的麻烦在于parseInt的第二个参数是可选的。但现在你已经吃过亏了,所以不会忘记了 :) - mu is too short

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接