最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - setDate() set the wrong date on 31st? - Stack Overflow

programmeradmin1浏览0评论

This is very weird I don't know what I'm doing wrong. I have a function to grab the date (i.e in this format: 06/24/2011), here's the function:

function checkDate(input){
    var d = new Date();
    var dspl = input.split("/");

    if(dspl.length != 3)
        return NaN;

    d.setDate(dspl[1]);

    d.setMonth(Number(dspl[0])-1);

    if(dspl[2].length == 2)
        d.setYear("20"+(dspl[2]+""));
    else if(dspl[2].length == 4)
        d.setYear(dspl[2]);
    else
        return NaN;

    var dt = jsToMsDate(new Date(d));
    return dt;
}

If I enter any date of the month, it would parse the date correctly, but if I enter 31st, i.e "01/31/2011", then it would turn into "01/01/2011". I'm not sure what to do and not really sure where the problem might be.

This is very weird I don't know what I'm doing wrong. I have a function to grab the date (i.e in this format: 06/24/2011), here's the function:

function checkDate(input){
    var d = new Date();
    var dspl = input.split("/");

    if(dspl.length != 3)
        return NaN;

    d.setDate(dspl[1]);

    d.setMonth(Number(dspl[0])-1);

    if(dspl[2].length == 2)
        d.setYear("20"+(dspl[2]+""));
    else if(dspl[2].length == 4)
        d.setYear(dspl[2]);
    else
        return NaN;

    var dt = jsToMsDate(new Date(d));
    return dt;
}

If I enter any date of the month, it would parse the date correctly, but if I enter 31st, i.e "01/31/2011", then it would turn into "01/01/2011". I'm not sure what to do and not really sure where the problem might be.

Share Improve this question edited Jun 24, 2011 at 17:30 Saxman asked Jun 24, 2011 at 17:23 SaxmanSaxman 5,08911 gold badges53 silver badges72 bronze badges 2
  • Have you checked what the new Date(d) at the end is doing v.s. your jsToMsDate() function? Could be JS is working fine but your jsToMs function is broken – Marc B Commented Jun 24, 2011 at 17:25
  • I've tried that, still displaying the 1st instead of 31st. – Saxman Commented Jun 24, 2011 at 17:32
Add a comment  | 

4 Answers 4

Reset to default 10

JavaScript's Date objects allow you to give invalid combinations of months and days; they automagically correct those for you (so for instance, if you set the day of the month to 31 when the month is June, it automatically makes it July 1st). That means if you set the fields individually, you can run into situations where that automagic correction gets in your way.

In your case, if you're going to set all three of those fields, you're better off using the form of the Date constructor that accepts them as arguments:

var dt = new Date(year, month, day);

(If you want hours, minutes, seconds, and milliseconds, you can add them as parameters as well.)

So looking at your code, an off-the-cuff update:

function checkDate(input){
    var year, month, day, d, dt;
    var dspl = input.split("/");

    if(dspl.length != 3)
        return NaN;

    year  = parseInt(dspl[2], 10);
    month = parseInt(dspl[0], 10) - 1;
    day   = parseInt(dspl[1], 10);
    if (isNaN(year) || isNaN(month) || isNaN(day)) {
        return NaN;
    }

    if (year < 100) {
        year += 2000;
    }

    d = new Date(year, month, day);

    var dt = jsToMsDate(d);
    return dt;
}

Some other notes on that update:

  • It's best to use parseInt to parse numbers from end users, and to always specify the radix (10 for decimal). (No, parseInt is not slower than Number or the unary + trick. People assume it is, but it isn't.)
  • No need to muck about with strings to add 2000 to years given with only two digits. But you can if you like. Note I weakened the validation there, allowing one-digit years for (say) 2001 and three-digit years for (say) 300 AD. So if you need it to be that strong, you'll need to readjust that.
  • No need to feed the date instance into new Date() again.

You need to set the month before setting the day (or as Marc B points out in his comment, use the Date(yearval, monthval, dayval) constructor).

When you create a Date object, it defaults to the current date. At the time of writing that's in June, so when you try to set the day to 31 it wraps.

...And because of similar behaviour in leap years, you should set the year before setting the month or day.

(It's a good job you developed this code in June rather than in July - the bug would have lurked undiscovered until September, and it would probably have been your users that found it rather than you. :-)

Right hierarchy is set year, then Month and at last add the Day. This will return the exact date that you added.

function checkDate() {

  //Wrong order-  will return 1 May 2016
  var start = new Date();
  start.setDate(31);
  start.setMonth(4);
  start.setFullYear(2016);
  alert(start)


  //Right  order - will return 31 May 2016
  var end = new Date();
  end.setFullYear(2016);
  end.setMonth(4);
  end.setDate(31);
  alert(end)


}
<input type="button" value="Test" onclick="checkDate()" />

This is the right heirarchy to set date.

Why are you adding 1 the day position (position 1)? I think that is your problem.

d.setDate(dspl[1] + 1);
发布评论

评论列表(0)

  1. 暂无评论