Skip to content

Method Chaining

Choose a tag to compare

@MelakuDemeke MelakuDemeke released this 15 Sep 16:05
· 7 commits to main since this release

Changelog

All notable changes to this project will be documented in this file.

3.1.0 - 2025-09-15

Added

  • Method chaining and immutability support in Kenat:
    • add(amount, 'days'|'months'|'years')
    • subtract(amount, 'days'|'months'|'years')
    • startOf('day'|'month'|'year')
    • endOf('day'|'month'|'year')
    • setTime(hour, minute, 'day'|'night') now returns a new instance
  • New test suite tests/methodChaining.test.js covering chaining, immutability, time preservation, error cases, leap-year handling, and boundaries.
  • Type definitions updated in types/Kenat.d.ts to include new chainable APIs.

Changed

  • Existing arithmetic methods now delegate to the new chainable API while preserving backward compatibility:
    • addDays(days), addMonths(months), addYears(years)
    • startOfMonth(), endOfMonth()

Fixed

  • addDays in src/dayArithmetic.js now correctly handles negative day offsets (moving backward across months/years).

Docs

  • Inline JSDoc improvements around new methods (chainability and immutability).

Performance/Behavioral Notes

  • All date operations are immutable—no mutation of the original Kenat instance.
  • Time component is preserved across date arithmetic by default.

Migration Notes

  • No breaking changes. Existing APIs continue to work.
  • Prefer new chainable methods for more fluent and readable code.

Examples

  • Basic chaining
const date1 = new Kenat('2017/1/1');
const future = date1.add(7, 'days').add(1, 'months').add(1, 'years');
console.log('Original:', date1.format());
console.log('After chaining:', future.format());
console.log('Result:', future.getEthiopian());

Output:

Original: መስከረም 1 2017
After chaining: ጥቅምት 8 2018
Result: { year: 2018, month: 2, day: 8 }
  • Subtract operations
const date2 = new Kenat('2017/1/1');
const past = date2.subtract(7, 'days').subtract(1, 'months').subtract(1, 'years');
console.log('Original:', date2.format());
console.log('After subtracting:', past.format());
console.log('Result:', past.getEthiopian());

Output:

Original: መስከረም 1 2017
After subtracting: ሀምሌ 29 2015
Result: { year: 2015, month: 11, day: 29 }
  • Mixed add and subtract
const date3 = new Kenat('2017/1/1');
const mixed = date3.add(7, 'days').subtract(1, 'months').add(1, 'years');
console.log('Original:', date3.format());
console.log('After mixed operations:', mixed.format());
console.log('Result:', mixed.getEthiopian());

Output:

Original: መስከረም 1 2017
After mixed operations: ጳጉሜ 5 2017
Result: { year: 2017, month: 13, day: 5 }
  • Time preservation
const date4 = new Kenat('2017/1/1', { hour: 3, minute: 30, period: 'day' });
const withTime = date4.add(7, 'days').add(1, 'months');
console.log('Original:', date4.toString());
console.log('After operations:', withTime.toString());
console.log('Time preserved:', withTime.time);

Output:

Original: መስከረም 1 2017 03:30 ጠዋት
After operations: ጥቅምት 8 2017 03:30 ጠዋት
Time preserved: { hour: 3, minute: 30, period: 'day' }
  • startOf and endOf chaining
const date5 = new Kenat('2017/6/15');
const res = date5.startOf('month').add(7, 'days').endOf('day');
console.log('Original:', date5.format());
console.log('After startOf/endOf:', res.format());
console.log('Time set to:', res.time);

Output:

Original: የካቲት 15 2017
After startOf/endOf: የካቲት 8 2017
Time set to: { hour: 12, minute: 0, period: 'night' }
  • Complex chaining
const date6 = new Kenat('2017/1/1');
const complex = date6
  .startOf('month')
  .add(14, 'days')
  .setTime(12, 0, 'day')
  .add(1, 'months')
  .endOf('day')
  .add(1, 'years');
console.log('Original:', date6.format());
console.log('After complex chaining:', complex.format());
console.log('Final result:', complex.getEthiopian());

Output:

Original: መስከረም 1 2017
After complex chaining: ጥቅምት 15 2018
Final result: { year: 2018, month: 2, day: 15 }
  • Leap year handling
const leapDate = new Kenat('2015/13/6');
const leapResult = leapDate.add(1, 'days').add(1, 'months');
console.log('Original (leap year):', leapDate.format());
console.log('After operations:', leapResult.format());
console.log('Result:', leapResult.getEthiopian());

Output:

Original (leap year): ጳጉሜ 6 2015
After operations: ጥቅምት 1 2016
Result: { year: 2016, month: 2, day: 1 }