JavaScript not rounding date properly

Refresh

April 2019

Views

45 time

1

//Expected: 2016-04-01 Actual: 2016-04-01
console.log(roundToQuarter(new Date("2016-05-30T23:39:35.418Z")));

//Expected: 2016-04-01 Actual: 2016-05-01
console.log(roundToQuarter(new Date("2016-05-31T00:21:55.875Z"))); 

//Expected: 2016-04-01 Actual: 2016-04-01
console.log(roundToQuarter(new Date("2016-06-10T00:11:22.124Z"))); 

function roundToQuarter( date ) {
	var monthIndex = Math.floor( date.getUTCMonth() / 3 );
	date.setUTCHours ( 0, 0, 0, 0 );
	date.setUTCMonth( monthIndex * 3 );
	date.setUTCDate( 1 );

	return date.toISOString();
}

I have written a script that takes an ISO date string and rounds it to the start of each quarter (1/1, 4/1, 7/1, 10/1).

I have found this odd edge case that affects seemingly arbitrary date ranges, and I cannot figure out why it is not rounding correctly. In this particular instance, it is rounding the entire day (5/31) to (5/1) when it should round to (4/1). This occurs at other dates too.

w0f

1 answers

1

As Tyler Roper and Xufox have suggested in comments, the date should be set before the month. If you change the month first, it will probably clash with the date as the new month may not have such date. That's the case for your second example. If the date is change to 1 first, then changing month afterwards is easy.

function roundToQuarter( date ) {
    date.setUTCHours ( 0, 0, 0, 0 );
    date.setUTCDate( 1 );
    date.setUTCMonth( Math.floor( date.getUTCMonth() / 3 ) * 3 );

    return date.toISOString();
}