Skip to content

Commit

Permalink
Merge pull request #30 from yyankowski/fix-leap-year-add-subtract
Browse files Browse the repository at this point in the history
fix operations with leap year
  • Loading branch information
yyankowski authored Oct 3, 2020
2 parents b2abd4b + 01e20cc commit 803f265
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 39 deletions.
24 changes: 14 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,21 @@ const determineLastDayOfMonth = (year: number, month: number): number => {

const subtractYears = (value: number) => (sDt: Readonly<SimplyDate>): SimplyDate => {

let day = sDt.day;
let { day, month } = sDt;
const year = sDt.year - value;
// if we are in the zone of days that may be bigger that the total days in the given month
// then take the last day of the given month

// when the source year is a leap year and the target is not
// i.e. February 29, 2020 minus 1 year should equal March 1, 2019
if (day > 28 && sDt.month === 2) {
if (isLeapYear(sDt.year) && !isLeapYear(year)) {
day = 28;
day = 1;
month = 3;
}
}

return {
year: sDt.year - value,
month: sDt.month,
month,
day,
hour: sDt.hour,
minute: sDt.minute,
Expand All @@ -122,7 +124,7 @@ const subtractYears = (value: number) => (sDt: Readonly<SimplyDate>): SimplyDate
* @param {number} value
* @returns {(sDt: SimplyDate) => SimplyDate}
*/
const subtractMonths = (value: number) => (sDt: Readonly<SimplyDate>): SimplyDate => {
const subtractMonths = (value: number) => (sDt: Readonly<SimplyDate>): SimplyDate => {
if (value < 0) {
return addMonths(-value)(sDt);
}
Expand Down Expand Up @@ -178,17 +180,19 @@ const addYears = (value: number) => (sDt: Readonly<SimplyDate>): SimplyDate => {
return subtractYears(value)(sDt);
}

let day = sDt.day;
let { day, month } = sDt;
const year = sDt.year + value;
if (sDt.month === 2 && day > 28) {
// special case from leap to a normal year
if (sDt.month === 2 && sDt.day > 28) {
if (isLeapYear(sDt.year) && !isLeapYear(year)) {
day = 28;
day = 1;
month = 3;
}
}

return {
year,
month: sDt.month,
month,
day,
hour: sDt.hour,
minute: sDt.minute,
Expand Down
62 changes: 33 additions & 29 deletions test/years.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,6 @@ describe('years.spec.ts', () => {
expect(day).to.equal(29);
});

it('1.1 correctly subtract from a leap year when the current month has more days than the resulting one', () => {
sDt = Simply.from.date(new Date('2020-02-29T03:24:00'));
const res = Simply.subtract(1).years.from(sDt);

expect(res.year).to.equal(2019);
expect(res.day).to.equal(28);
});

it('1.2 correctly subtract from a leap year when the resulting year is also a leap year', () => {
sDt = Simply.from.date(new Date('2024-02-29T03:24:00'));
const res = Simply.subtract(4).years.from(sDt);

expect(res.year).to.equal(2020);
expect(res.day).to.equal(29);
});

it('1.3 correctly add years', () => {
sDt = Simply.from.date(new Date('2017-03-29T03:24:00'));
const { year, day, month } = Simply.add(10).years.to(sDt);
Expand All @@ -35,19 +19,39 @@ describe('years.spec.ts', () => {
expect(day).to.equal(29);
});

it('1.4 correctly add to a leap year', () => {
sDt = Simply.from.date(new Date('2020-02-29T03:24:00'));
const { year, day, month } = Simply.add(1).years.to(sDt);
expect(year).to.equal(2021);
expect(month).to.equal(2);
expect(day).to.equal(28);
});
describe('Edge cases', () => {
it('1.1 correctly subtract from a leap year when the current month has more days than the resulting one', () => {
sDt = Simply.from.date(new Date('2020-02-29T03:24:00'));
const { year, month, day } = Simply.subtract(1).years.from(sDt);

expect(year).to.equal(2019);
expect(month).to.equal(3);
expect(day).to.equal(1);
});

it('1.2 correctly subtract from a leap year when the resulting year is also a leap year', () => {
sDt = Simply.from.date(new Date('2024-02-29T03:24:00'));
const res = Simply.subtract(4).years.from(sDt);

expect(res.year).to.equal(2020);
expect(res.day).to.equal(29);
});

it('1.4 correctly add to a leap year', () => {
sDt = Simply.from.date(new Date('2020-02-29T03:24:00'));
const { year, day, month } = Simply.add(1).years.to(sDt);
expect(year).to.equal(2021);
expect(month).to.equal(3);
expect(day).to.equal(1);
});

it('1.5 correctly add to a leap year when the result is also a leap year', () => {
sDt = Simply.from.date(new Date('2020-02-29T03:24:00'));
const { year, day, month } = Simply.add(4).years.to(sDt);
expect(year).to.equal(2024);
expect(month).to.equal(2);
expect(day).to.equal(29);
});

it('1.5 correctly add to a leap year when the result is also a leap year', () => {
sDt = Simply.from.date(new Date('2020-02-29T03:24:00'));
const { year, day, month } = Simply.add(4).years.to(sDt);
expect(year).to.equal(2024);
expect(month).to.equal(2);
expect(day).to.equal(29);
});
});

0 comments on commit 803f265

Please sign in to comment.