differenceInYears.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { normalizeDates } from "./_lib/normalizeDates.js";
  2. import { compareAsc } from "./compareAsc.js";
  3. import { differenceInCalendarYears } from "./differenceInCalendarYears.js";
  4. /**
  5. * The {@link differenceInYears} function options.
  6. */
  7. /**
  8. * @name differenceInYears
  9. * @category Year Helpers
  10. * @summary Get the number of full years between the given dates.
  11. *
  12. * @description
  13. * Get the number of full years between the given dates.
  14. *
  15. * @param laterDate - The later date
  16. * @param earlierDate - The earlier date
  17. * @param options - An object with options
  18. *
  19. * @returns The number of full years
  20. *
  21. * @example
  22. * // How many full years are between 31 December 2013 and 11 February 2015?
  23. * const result = differenceInYears(new Date(2015, 1, 11), new Date(2013, 11, 31))
  24. * //=> 1
  25. */
  26. export function differenceInYears(laterDate, earlierDate, options) {
  27. const [laterDate_, earlierDate_] = normalizeDates(
  28. options?.in,
  29. laterDate,
  30. earlierDate,
  31. );
  32. // -1 if the left date is earlier than the right date
  33. // 2023-12-31 - 2024-01-01 = -1
  34. const sign = compareAsc(laterDate_, earlierDate_);
  35. // First calculate the difference in calendar years
  36. // 2024-01-01 - 2023-12-31 = 1 year
  37. const diff = Math.abs(differenceInCalendarYears(laterDate_, earlierDate_));
  38. // Now we need to calculate if the difference is full. To do that we set
  39. // both dates to the same year and check if the both date's month and day
  40. // form a full year.
  41. laterDate_.setFullYear(1584);
  42. earlierDate_.setFullYear(1584);
  43. // For it to be true, when the later date is indeed later than the earlier date
  44. // (2026-02-01 - 2023-12-10 = 3 years), the difference is full if
  45. // the normalized later date is also later than the normalized earlier date.
  46. // In our example, 1584-02-01 is earlier than 1584-12-10, so the difference
  47. // is partial, hence we need to subtract 1 from the difference 3 - 1 = 2.
  48. const partial = compareAsc(laterDate_, earlierDate_) === -sign;
  49. const result = sign * (diff - +partial);
  50. // Prevent negative zero
  51. return result === 0 ? 0 : result;
  52. }
  53. // Fallback for modularized imports:
  54. export default differenceInYears;