Skip to content

intervalOverlappingDaysDate

intervalOverlappingDaysDate(aStart: string, aEnd: string, bStart: string, bEnd: string): number
import { intervalOverlappingDaysDate } from "@northguild/gmt/plain/interval";

Return how many distinct calendar dates two date intervals share.

  • Counts the number of dates touched by the closed intersection [max(aStart, bStart), min(aEnd, bEnd)] — inclusive of both endpoints.
  • Adjacent intervals (e.g. aEnd === bStart) share one date and count as 1.
  • Returns 0 when the intervals do not overlap at all (a well-defined answer, not invalid input).
  • Returns null if either interval is invalid (start > end).
  • Returns null on invalid input (wrong type, malformed strings).
  • Diverges from date-fns’s getOverlappingDaysInIntervals, which rounds up elapsed 24-hour periods instead of counting calendar dates (its own doc example — Jan 10-20 vs Jan 17-21 — returns 3 there, 4 here). To reproduce date-fns’s number, compose intervalIntersectionDate with intervalCountDate: const span = intervalIntersectionDate(aStart, aEnd, bStart, bEnd); span ? intervalCountDate(span.start, span.end, "day") : 0;
  • Accepts GMT calendar-annotated PlainDate strings — E5 (issue #78). A day is a day in every supported calendar, so this returns the same count whether or not the endpoints are calendar-tagged, and arguments may carry different or no tags (D4).
Parameter Type Description
aStart string ISO 8601 date string for the first interval start, optionally calendar-annotated
aEnd string ISO 8601 date string for the first interval end, optionally calendar-annotated
bStart string ISO 8601 date string for the second interval start, optionally calendar-annotated
bEnd string ISO 8601 date string for the second interval end, optionally calendar-annotated

number of shared calendar dates, 0 when disjoint, or null on invalid input

intervalOverlappingDaysDate("2024-01-01", "2024-06-30", "2024-04-01", "2024-12-31") // 91
intervalOverlappingDaysDate("2024-01-01", "2024-12-31", "2024-02-01", "2024-02-29") // 29
intervalOverlappingDaysDate("2024-01-01", "2024-06-30", "2024-06-30", "2024-12-31") // 1 (adjacent)
intervalOverlappingDaysDate("2024-01-01", "2024-06-30", "2024-07-01", "2024-12-31") // 0 (disjoint)
intervalOverlappingDaysDate("invalid", "2024-06-30", "2024-04-01", "2024-12-31") // null

plain/interval/intervalOverlappingDaysDate.ts