diff --git a/src/datepicker/ngb-calendar.spec.ts b/src/datepicker/ngb-calendar.spec.ts index 94b087c7b4..a60bf48bd5 100644 --- a/src/datepicker/ngb-calendar.spec.ts +++ b/src/datepicker/ngb-calendar.spec.ts @@ -44,25 +44,41 @@ describe('ngb-calendar-gregorian', () => { }); it('should add months to date', () => { - expect(calendar.getNext(new NgbDate(2016, 7, 22), 'm')).toEqual(new NgbDate(2016, 8, 1)); + expect(calendar.getNext(new NgbDate(2016, 7, 22), 'm')).toEqual(new NgbDate(2016, 8, 22)); expect(calendar.getNext(new NgbDate(2016, 7, 1), 'm')).toEqual(new NgbDate(2016, 8, 1)); - expect(calendar.getNext(new NgbDate(2016, 12, 22), 'm')).toEqual(new NgbDate(2017, 1, 1)); + expect(calendar.getNext(new NgbDate(2016, 12, 22), 'm')).toEqual(new NgbDate(2017, 1, 22)); + expect(calendar.getNext(new NgbDate(2016, 1, 29), 'm')).toEqual(new NgbDate(2016, 2, 29)); + expect(calendar.getNext(new NgbDate(2016, 1, 30), 'm')).toEqual(new NgbDate(2016, 2, 29)); + expect(calendar.getNext(new NgbDate(2016, 10, 30), 'm', 6)).toEqual(new NgbDate(2017, 4, 30)); + expect(calendar.getNext(new NgbDate(2016, 10, 31), 'm', 6)).toEqual(new NgbDate(2017, 4, 30)); }); it('should subtract months from date', () => { - expect(calendar.getPrev(new NgbDate(2016, 7, 22), 'm')).toEqual(new NgbDate(2016, 6, 1)); + expect(calendar.getPrev(new NgbDate(2016, 7, 22), 'm')).toEqual(new NgbDate(2016, 6, 22)); expect(calendar.getPrev(new NgbDate(2016, 8, 1), 'm')).toEqual(new NgbDate(2016, 7, 1)); - expect(calendar.getPrev(new NgbDate(2017, 1, 22), 'm')).toEqual(new NgbDate(2016, 12, 1)); + expect(calendar.getPrev(new NgbDate(2017, 1, 22), 'm')).toEqual(new NgbDate(2016, 12, 22)); + expect(calendar.getPrev(new NgbDate(2016, 3, 29), 'm')).toEqual(new NgbDate(2016, 2, 29)); + expect(calendar.getPrev(new NgbDate(2016, 3, 30), 'm')).toEqual(new NgbDate(2016, 2, 29)); + expect(calendar.getPrev(new NgbDate(2016, 10, 30), 'm', 4)).toEqual(new NgbDate(2016, 6, 30)); + expect(calendar.getPrev(new NgbDate(2016, 10, 31), 'm', 4)).toEqual(new NgbDate(2016, 6, 30)); }); it('should add years to date', () => { - expect(calendar.getNext(new NgbDate(2016, 1, 22), 'y')).toEqual(new NgbDate(2017, 1, 1)); - expect(calendar.getNext(new NgbDate(2017, 12, 22), 'y')).toEqual(new NgbDate(2018, 1, 1)); + expect(calendar.getNext(new NgbDate(2016, 1, 22), 'y')).toEqual(new NgbDate(2017, 1, 22)); + expect(calendar.getNext(new NgbDate(2017, 12, 22), 'y')).toEqual(new NgbDate(2018, 12, 22)); + expect(calendar.getNext(new NgbDate(2016, 2, 29), 'y')).toEqual(new NgbDate(2017, 2, 28)); + expect(calendar.getNext(new NgbDate(2016, 2, 28), 'y')).toEqual(new NgbDate(2017, 2, 28)); + expect(calendar.getNext(new NgbDate(2016, 2, 29), 'y', 4)).toEqual(new NgbDate(2020, 2, 29)); + expect(calendar.getNext(new NgbDate(2016, 2, 29), 'y', 3)).toEqual(new NgbDate(2019, 2, 28)); }); it('should subtract years from date', () => { - expect(calendar.getPrev(new NgbDate(2016, 12, 22), 'y')).toEqual(new NgbDate(2015, 1, 1)); - expect(calendar.getPrev(new NgbDate(2017, 1, 22), 'y')).toEqual(new NgbDate(2016, 1, 1)); + expect(calendar.getPrev(new NgbDate(2016, 12, 22), 'y')).toEqual(new NgbDate(2015, 12, 22)); + expect(calendar.getPrev(new NgbDate(2017, 1, 22), 'y')).toEqual(new NgbDate(2016, 1, 22)); + expect(calendar.getPrev(new NgbDate(2016, 2, 28), 'y')).toEqual(new NgbDate(2015, 2, 28)); + expect(calendar.getPrev(new NgbDate(2016, 2, 29), 'y')).toEqual(new NgbDate(2015, 2, 28)); + expect(calendar.getPrev(new NgbDate(2016, 2, 29), 'y', 4)).toEqual(new NgbDate(2012, 2, 29)); + expect(calendar.getPrev(new NgbDate(2016, 2, 29), 'y', 3)).toEqual(new NgbDate(2013, 2, 28)); }); it('should check that NgbDate is a valid javascript date', () => { diff --git a/src/datepicker/ngb-calendar.ts b/src/datepicker/ngb-calendar.ts index 3d50aed8dc..4d00d58835 100644 --- a/src/datepicker/ngb-calendar.ts +++ b/src/datepicker/ngb-calendar.ts @@ -43,20 +43,35 @@ export class NgbCalendarGregorian extends NgbCalendar { getNext(date: NgbDate, period: NgbPeriod = 'd', number = 1) { let jsDate = toJSDate(date); + let checkMonth = true; + let expectedMonth = jsDate.getMonth(); switch (period) { case 'y': - return new NgbDate(date.year + number, 1, 1); + jsDate.setFullYear(jsDate.getFullYear() + number); + break; case 'm': - jsDate = new Date(date.year, date.month + number - 1, 1); + expectedMonth += number; + jsDate.setMonth(expectedMonth); + expectedMonth = expectedMonth % 12; + if (expectedMonth < 0) { + expectedMonth = expectedMonth + 12; + } break; case 'd': jsDate.setDate(jsDate.getDate() + number); + checkMonth = false; break; default: return date; } + if (checkMonth && jsDate.getMonth() !== expectedMonth) { + // this means the destination month has less days than the initial month + // let's go back to the end of the previous month: + jsDate.setDate(0); + } + return fromJSDate(jsDate); }