-
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* differenceInMilliseconds * created the other constant difference functions, but will need to add the option 'ignoreTime' for day/week version * created the other constant difference functions * completing tests * adding differenceInX exports in index * make sure that rounding doesn't give -0 * added difference In Months & years * shortened the all difference functions to diffX moved using monthDays at diffMonths after `if (ld < rd)` * raname type DifferenceRoundingMethod -> DiffRoundingMethod
- Loading branch information
Showing
18 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { describe, expect, it } from "vitest" | ||
import { diffDays } from "../diffDays" | ||
|
||
describe("differenceInDays", () => { | ||
it("difference is 3 days", () => { | ||
expect(diffDays("2024-04-10", "2024-04-07")).toBe(3) | ||
}) | ||
|
||
it("difference is 2 days", () => { | ||
expect( | ||
diffDays("2024-04-10T09:50:00.000Z", "2024-04-07T15:28:00.000Z") | ||
).toBe(2) | ||
}) | ||
|
||
it("difference is 3 days by using round", () => { | ||
expect( | ||
diffDays("2024-04-10T09:50:00.000Z", "2024-04-07T15:28:00.000Z", "round") | ||
).toBe(3) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { describe, expect, it } from "vitest" | ||
import { diffHours } from "../diffHours" | ||
|
||
describe("differenceInHours", () => { | ||
it("difference is 5 hours", () => { | ||
expect( | ||
diffHours("2024-04-07T15:28:00.000Z", "2024-04-07T09:50:00.000Z") | ||
).toBe(5) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { describe, it, expect } from "vitest" | ||
import { diffMilliseconds } from "../diffMilliseconds" | ||
|
||
describe("differenceInMilliseconds", () => { | ||
it("difference is 257 milliseconds", () => { | ||
expect( | ||
diffMilliseconds("2024-04-07T09:10:48.257Z", "2024-04-07T09:10:48.000Z") | ||
).toBe(257) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { describe, it, expect } from "vitest" | ||
import { diffMinutes } from "../diffMinutes" | ||
|
||
describe("differenceInMinutes", () => { | ||
it("difference is 18 minutes", () => { | ||
expect( | ||
diffMinutes("2024-04-07T09:28:30.050Z", "2024-04-07T09:10:00.000Z") | ||
).toBe(18) | ||
}) | ||
it("difference is 19 minutes by using ceil", () => { | ||
expect( | ||
diffMinutes( | ||
"2024-04-07T09:28:01.050Z", | ||
"2024-04-07T09:10:00.000Z", | ||
"ceil" | ||
) | ||
).toBe(19) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { describe, it, expect } from "vitest" | ||
import { diffMonths } from "../diffMonths" | ||
|
||
describe("differenceInMonths", () => { | ||
it("should give 11 months", () => { | ||
expect(diffMonths("2025-04-13", "2024-04-14")).toBe(11) | ||
}) | ||
|
||
it("should give 12 months", () => { | ||
expect(diffMonths("2025-04-14", "2024-04-14")).toBe(12) | ||
}) | ||
|
||
it("should give a negative amount when the right side is in the future", () => { | ||
expect(diffMonths("2024-04-14", "2025-04-15")).toBe(-12) | ||
}) | ||
|
||
it("should give 8 months" /* till it's xmas */, () => { | ||
expect(diffMonths("2024-12-25", "2024-04-13")).toBe(8) | ||
}) | ||
|
||
it("should give 3 full months", () => { | ||
expect(diffMonths("2024-04-13", "2023-12-25")).toBe(3) // not yet full 4 months | ||
}) | ||
|
||
it("should still be a full month even if the left one is shorter", () => { | ||
expect(diffMonths("2024-02-29", "2024-01-31")).toBe(1) | ||
}) | ||
|
||
it("should also be a negative full month when swapped", () => { | ||
expect(diffMonths("2024-01-31", "2024-02-29")).toBe(-1) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { describe, it, expect } from "vitest" | ||
import { diffSeconds } from "../diffSeconds" | ||
|
||
describe("differenceInSeconds", () => { | ||
it("difference is 28 seconds", () => { | ||
expect( | ||
diffSeconds("2024-04-07T09:10:28.900Z", "2024-04-07T09:10:00.000Z") | ||
).toBe(28) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { describe, expect, it } from "vitest" | ||
import { diffWeeks } from "../diffWeeks" | ||
|
||
describe("differenceInWeeks", () => { | ||
it("difference is 5 hours", () => { | ||
expect(diffWeeks("2025-06-30", "2024-04-07")).toBe(64) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { describe, it, expect, suite } from "vitest" | ||
import { diffYears } from "../diffYears" | ||
|
||
describe("differenceInYears", () => { | ||
it("returns the amount of full years between dates", () => { | ||
expect(diffYears("2025-04-20", "2024-03-31")).toBe(1) | ||
}) | ||
|
||
it("returns a negative number when swapped around as the first is now smaller", () => { | ||
expect(diffYears("2024-03-31", "2025-04-20")).toBe(-1) | ||
}) | ||
|
||
// date-fns had a lot of tests for the leap day | ||
// although because differenceInMonth/year doesn't depend on time it shouldn't be an issue | ||
suite("leap days", () => { | ||
it("supports right side dates that are after a leap day", () => { | ||
expect(diffYears("2024-02-29", "2022-03-01")).toBe(1) | ||
}) | ||
|
||
it("And also supports if right side date is before the leap date", () => { | ||
expect(diffYears("2024-02-29", "2022-02-28")).toBe(2) | ||
}) | ||
|
||
it("supports future dates", () => { | ||
expect(diffYears("2024-02-29", "2026-03-10")).toBe(-2) | ||
}) | ||
|
||
it("equal (leap) day give 0", () => { | ||
expect(diffYears("2024-02-28", "2024-02-28")).toBe(0) | ||
}) | ||
|
||
it("Futute (leap) dates supported", () => { | ||
expect(diffYears("2028-02-29", "2024-02-29")).toBe(4) | ||
}) | ||
}) | ||
|
||
// some of the edge cases are also tested with leap days | ||
suite("edge cases", () => { | ||
it("difference is less than a year because of 1 day difference", () => { | ||
// NL kings day | ||
expect(diffYears("2025-04-26", "2024-04-27")).toBe(0) | ||
}) | ||
|
||
it("same but swapped", () => { | ||
expect(diffYears("2024-04-27", "2025-04-26")).toBe(0) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { diffMilliseconds } from "./diffMilliseconds" | ||
import { DateInput } from "./types" | ||
import { diffRound, type DiffRoundingMethod } from "./diffRound" | ||
|
||
/** | ||
* Returns the difference between 2 dates in days. | ||
* @param leftDate A date to compare with the right date | ||
* @param rightDate A date to compare with the left date | ||
* @param roundingMethod the rounding method to use, default: trunc | ||
*/ | ||
export function diffDays( | ||
leftDate: DateInput, | ||
rightDate: DateInput, | ||
roundingMethod?: DiffRoundingMethod | ||
) { | ||
return diffRound( | ||
diffMilliseconds(leftDate, rightDate) / 86_400_000, // hour * 24 | ||
roundingMethod | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { diffMilliseconds } from "./diffMilliseconds" | ||
import { diffRound, type DiffRoundingMethod } from "./diffRound" | ||
import { DateInput } from "./types" | ||
|
||
/** | ||
* Returns the difference between 2 dates in hours. | ||
* @param leftDate A date to compare with the right date | ||
* @param rightDate A date to compare with the left date | ||
* @param roundingMethod the rounding method to use, default: trunc | ||
*/ | ||
export function diffHours( | ||
leftDate: DateInput, | ||
rightDate: DateInput, | ||
roundingMethod?: DiffRoundingMethod | ||
) { | ||
return diffRound( | ||
diffMilliseconds(leftDate, rightDate) / 3_600_000, // 1000 * 60 * 60 | ||
roundingMethod | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { date } from "./date" | ||
import { DateInput } from "./types" | ||
|
||
/** | ||
* Returns the difference between 2 dates in milliseconds. | ||
* @param leftDate A date to compare with the right date | ||
* @param rightDate A date to compare with the left date | ||
*/ | ||
export function diffMilliseconds(leftDate: DateInput, rightDate: DateInput) { | ||
const left = date(leftDate) | ||
const right = date(rightDate) | ||
return +left - +right | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { DateInput } from "./types" | ||
import { diffMilliseconds } from "./diffMilliseconds" | ||
import { diffRound, type DiffRoundingMethod } from "./diffRound" | ||
|
||
/** | ||
* Returns the difference between 2 dates in minutes. | ||
* @param leftDate A date to compare with the right date | ||
* @param roundingMethod the rounding method to use, default: trunc | ||
*/ | ||
export function diffMinutes( | ||
leftDate: DateInput, | ||
rightDate: DateInput, | ||
roundingMethod?: DiffRoundingMethod | ||
) { | ||
return diffRound( | ||
diffMilliseconds(leftDate, rightDate) / 60_000, | ||
roundingMethod | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { date } from "./date" | ||
import { DateInput } from "./types" | ||
import { monthDays } from "./monthDays" | ||
|
||
/** | ||
* Returns the difference between 2 dates in months. | ||
* @param left A date to compare with the right date | ||
* @param right A date to compare with the left date | ||
*/ | ||
export function diffMonths(left: DateInput, right: DateInput): number { | ||
const l = date(left) | ||
const r = date(right) | ||
// if the right one is bigger, we switch them around as it's easier to do | ||
if (l < r) { | ||
const rs = diffMonths(r, l) | ||
return rs == 0 ? 0 : -rs | ||
} | ||
|
||
// we first get the amount of calendar months | ||
let months = | ||
(l.getFullYear() - r.getFullYear()) * 12 + (l.getMonth() - r.getMonth()) | ||
|
||
const ld = l.getDate() | ||
const rd = r.getDate() | ||
|
||
// if no full month has passed we may subtract a month from the calendar months so we get the amount of full months | ||
if (ld < rd) { | ||
// in case left date is the last day of the month & the right date is higher, we don't subtract as a full month did actually pass | ||
const lm = monthDays(l) | ||
if (!(lm == ld && lm < rd)) { | ||
months-- | ||
} | ||
} | ||
//ensures we don't give back -0 | ||
return months == 0 ? 0 : months | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export type DiffRoundingMethod = "trunc" | "round" | "floor" | "ceil" | ||
|
||
/** | ||
* Return a rounded value with the given rounding method | ||
* @param value the value to round | ||
* @param method the rounding method | ||
*/ | ||
export function diffRound(value: number, method: DiffRoundingMethod = "trunc") { | ||
const r = Math[method](value) | ||
return r == 0 ? 0 : r | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { diffMilliseconds } from "./diffMilliseconds" | ||
import { DiffRoundingMethod, diffRound } from "./diffRound" | ||
import { DateInput } from "./types" | ||
|
||
/** | ||
* Returns the difference between 2 dates in seconds. | ||
* @param leftDate A date to compare with the right date | ||
* @param rightDate A date to compare with the left date | ||
* @param roundingMethod the rounding method to use, default: trunc | ||
*/ | ||
export function diffSeconds( | ||
leftDate: DateInput, | ||
rightDate: DateInput, | ||
roundingMethod?: DiffRoundingMethod | ||
) { | ||
return diffRound(diffMilliseconds(leftDate, rightDate) / 1000, roundingMethod) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { diffMilliseconds } from "./diffMilliseconds" | ||
import { DateInput } from "./types" | ||
import { diffRound, type DiffRoundingMethod } from "./diffRound" | ||
|
||
/** | ||
* Returns the difference between 2 dates in days. | ||
* @param leftDate A date to compare with the right date | ||
* @param rightDate A date to compare with the left date | ||
* @param roundingMethod the rounding method to use, default: trunc | ||
*/ | ||
export function diffWeeks( | ||
leftDate: DateInput, | ||
rightDate: DateInput, | ||
roundingMethod?: DiffRoundingMethod | ||
) { | ||
return diffRound( | ||
diffMilliseconds(leftDate, rightDate) / 604800000, // day * 7 | ||
roundingMethod | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { diffMonths } from "./diffMonths" | ||
import { DateInput } from "./types" | ||
|
||
/** | ||
* Returns the difference between 2 dates in years. | ||
* @param left A date to compare with the right date | ||
* @param right A date to compare with the left date | ||
*/ | ||
export function diffYears(left: DateInput, right: DateInput): number { | ||
const r = Math.trunc(diffMonths(left, right) / 12) | ||
//ensures we don't give back -0 | ||
return r == 0 ? 0 : r | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters