Sisir
Sisir

Reputation: 2816

JS Date Object setUTCMonth() increase months by two?

I have very weird situation where I am setting UTC month value for an date object using setUTCMonth() method. But it is getting increased by two.

My written code outputs on console start and end day of months.

// user input 

var start_month = 1;
var start_year = 2013;

var end_month = 6;
var end_year = 2013;

// code

start_month = start_month - 1;
end_month = end_month - 1;

var start_date = new Date();
start_date.setFullYear(start_year);
start_date.setUTCMonth(start_month);

var end_date = new Date(end_year, end_month);
end_date.setFullYear(end_year);
end_date.setUTCMonth(end_month);

console.log('<< START >>');
start_end_log(start_date, end_date);

function start_end_log(start_date, end_date){
    
     if(start_date.getFullYear() == end_date.getFullYear() 
        && start_date.getUTCMonth() == end_date.getUTCMonth()
       ){
         console.log('<< THE END >>');
         return;
     }
    
    start_date.setUTCDate(1); // go back to frist day of the month
    var start_date_str = start_date.toISOString().substr(0, 10); // get first day
    start_date.setUTCMonth(start_date.getUTCMonth() + 1); // increase to next month
    start_date.setUTCDate(0); // go back to last day of last month
    var end_date_str  = start_date.toISOString().substr(0, 10); // get last day

    console.log('start date: ' + start_date_str + ' End date: ' + end_date_str);
    
    var month = start_date.getUTCMonth();
    console.log('current month ' + month);
    
    month++;
    console.log('after increment month ' + month);
    
    start_date.setUTCMonth(month); // go to next month
    console.log('Check after setting month ' + start_date.getUTCMonth()); // why it is increasing by 2? :(
    
    start_end_log(start_date, end_date);
    
}

JS fiddle http://jsfiddle.net/jhg7ddjh/

I am outputting the month number just after setting it on console. I do not understand how it get increased by two.

Solved

Before calling getUTCMonth() the date needed to set back to a date that is available for next month.

Changed

start_date.setUTCMonth(month); // go to next month

to

start_date.setUTCDate(1);
start_date.setUTCMonth(month); // go to next month

Upvotes: 2

Views: 489

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1073978

This line:

start_date.setUTCDate(0);  // go back to last day of last month

...means start_date will be on the last day of a month. In your example, that month is January, which has 31 days, so now start_date is on 31/01/2015 (despite start_date_str being "01/01/2015", and since you use start_date_str, not start_date, in your console.log statement, it's fairly confusing to read the output).

Then you do

var month = start_date.getUTCMonth();
console.log('current month ' + month);

month++;
console.log('after increment month ' + month);

...which sets the month to 1 (February) on a date with a day value of 31, giving you (in theory) 31/02/2015 — you see the problem, there aren't 31 days in February.

JavaScript dates are smart, and so it adjusts that to 03/03/2015 (March, month #2), and so when you call getUTCMonth, you get back 2, not 1.

Upvotes: 3

Related Questions