d3.time.month.offset, or what fun Date.prototype.setMonth() is not

194 views
Skip to first unread message

Sean Upton

unread,
Mar 9, 2015, 5:06:59 PM3/9/15
to d3...@googlegroups.com
When using offsets with irregular intervals, "calendar math" is generally desired, but JavaScript does few favors for us on this front:

> date = new Date('Tue Mar 31 2015 16:59:59 GMT-0600 (MDT)');
  < Tue Mar 31 2015 16:59:59 GMT-0600 (MDT)
> date.getMonth()
  < 2
> date.setMonth(date.getMonth() + 1)
  < 1430521199000
> date.getMonth()  // 2 + 1 == 4?  Yikes.
  < 4
> date
  < Fri May 01 2015 16:59:59 GMT-0600 (MDT)

d3.time.month.offset() exposes this detail:

> date = new Date('Tue Mar 31 2015 16:59:59 GMT-0600 (MDT)');
  < Tue Mar 31 2015 16:59:59 GMT-0600 (MDT)
> d3.time.month.offset(date, 1)  // I really want 2015-04-30...
  < Fri May 01 2015 16:59:59 GMT-0600 (MDT)

...which makes it less than suitable to do something like calculate the end of a three-month quarter given a start date.

My sense is that moment.js gets this right:

> moment.utc('2015-03-31T23:59:59').add(1, 'months').toDate()
  < Date 2015-04-30T23:59:59.000Z
> moment.utc(moment.utc('2015-04-01T00:00:00').add(3, 'months').toDate() - 1).toDate()
  < Date 2015-06-30T23:59:59.999Z
 
But I am unsure if that means d3 gets this wrong?  Or are D3 intervals just unsuitable for strictly calendar-based boundary calculation?

Thoughts?

Sean
Reply all
Reply to author
Forward
0 new messages