Skip to content

Commit 8bec95d

Browse files
committed
feat: implementing new diffMethods
Implementing differenceInHours, differenceInSeconds and differenceInMs
1 parent ba14036 commit 8bec95d

10 files changed

Lines changed: 285 additions & 2 deletions

package-lock.json

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/methods/difference-in-hours.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { scales } from './constants';
2+
3+
export function differenceInHours<T extends Date, R extends Date>(
4+
this: T,
5+
start: R,
6+
) {
7+
return Math.trunc((this.getTime() - start.getTime()) / scales.addHours);
8+
}

src/methods/difference-in-ms.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export function differenceInMs<T extends Date, R extends Date>(
2+
this: T,
3+
start: R,
4+
) {
5+
return this.getTime() - start.getTime();
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { scales } from './constants';
2+
3+
export function differenceInSeconds<T extends Date, R extends Date>(
4+
this: T,
5+
start: R,
6+
) {
7+
return Math.trunc((this.getTime() - start.getTime()) / scales.addSeconds);
8+
}

src/methods/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ export * from './base-methods';
33
export * from './comparisons';
44
export * from './difference-in-days';
55
export * from './difference-in-minutes';
6+
export * from './difference-in-hours';
7+
export * from './difference-in-seconds';
8+
export * from './difference-in-ms';
69
export * from './difference-in-days';
710
export * from './difference-in-years';
811
export * from './minutes-from-midnight';

src/sonic-date.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,140 @@ export class SonicDate extends Date {
88
}
99
}
1010
export interface SonicDate {
11+
/**
12+
* Create a new `SonicDate` instance with the same time value.
13+
* @returns A cloned `SonicDate`.
14+
*/
1115
clone(): SonicDate;
16+
17+
/**
18+
* Returns true if this date is after the given date.
19+
* @param dateToCompare - Date, timestamp or ISO string to compare against.
20+
* @returns `true` when this date > `dateToCompare`.
21+
*/
1222
isAfter(dateToCompare: Dateable): boolean;
23+
24+
/**
25+
* Returns true if this date is before the given date.
26+
* @param dateToCompare - Date, timestamp or ISO string to compare against.
27+
* @returns `true` when this date < `dateToCompare`.
28+
*/
1329
isBefore(dateToCompare: Dateable): boolean;
30+
31+
/**
32+
* Add milliseconds to this date (mutates) and return `this`.
33+
* @param amount - Milliseconds to add (may be negative).
34+
* @returns The mutated `SonicDate` instance.
35+
*/
1436
addMilliseconds(amount: number): this;
37+
38+
/**
39+
* Add seconds to this date (mutates) and return `this`.
40+
* @param amount - Seconds to add (may be negative).
41+
* @returns The mutated `SonicDate` instance.
42+
*/
1543
addSeconds(amount: number): this;
44+
45+
/**
46+
* Add minutes to this date (mutates) and return `this`.
47+
* @param amount - Minutes to add (may be negative).
48+
* @returns The mutated `SonicDate` instance.
49+
*/
1650
addMinutes(amount: number): this;
51+
52+
/**
53+
* Add hours to this date (mutates) and return `this`.
54+
* @param amount - Hours to add (may be negative).
55+
* @returns The mutated `SonicDate` instance.
56+
*/
1757
addHours(amount: number): this;
58+
59+
/**
60+
* Add days to this date (mutates) and return `this`.
61+
* @param amount - Days to add (may be negative).
62+
* @returns The mutated `SonicDate` instance.
63+
*/
1864
addDays(amount: number): this;
65+
66+
/**
67+
* Add months to this date (mutates) and return `this`.
68+
* @param amount - Months to add (may be negative).
69+
* @returns The mutated `SonicDate` instance.
70+
*/
1971
addMonths(amount: number): this;
72+
73+
/**
74+
* Add years to this date (mutates) and return `this`.
75+
* @param amount - Years to add (may be negative).
76+
* @returns The mutated `SonicDate` instance.
77+
*/
2078
addYears(amount: number): this;
79+
80+
/**
81+
* Set time to the start of the day (00:00:00.000) and return `this`.
82+
* @returns The mutated `SonicDate` instance set to local start of day.
83+
*/
2184
startOfDay(): this;
85+
86+
/**
87+
* Get the minutes elapsed since local midnight (0-1439).
88+
* @returns Number of minutes from midnight.
89+
*/
2290
minutesFromMidnight(): number;
91+
92+
/**
93+
* Get the number of full minutes between this date and `dateRight`.
94+
* @param dateRight - Date, timestamp or ISO string to compare against.
95+
* @returns Floor of minutes difference (this - dateRight).
96+
*/
2397
differenceInMinutes(dateRight: Dateable): number;
98+
99+
/**
100+
* Get the number of full hours between this date and `dateRight`.
101+
* @param dateRight - Date, timestamp or ISO string to compare against.
102+
* @returns Floor of hours difference (this - dateRight).
103+
*/
104+
differenceInHours(dateRight: Dateable): number;
105+
106+
/**
107+
* Get the number of full seconds between this date and `dateRight`.
108+
* @param dateRight - Date, timestamp or ISO string to compare against.
109+
* @returns Floor of seconds difference (this - dateRight).
110+
*/
111+
differenceInSeconds(dateRight: Dateable): number;
112+
113+
/**
114+
* Get the difference in milliseconds between this date and `dateRight`.
115+
* @param dateRight - Date, timestamp or ISO string to compare against.
116+
* @returns Milliseconds difference (this - dateRight).
117+
*/
118+
differenceInMs(dateRight: Dateable): number;
119+
120+
/**
121+
* Get the number of full calendar days between this date and `dateRight`.
122+
* @param dateRight - Date, timestamp or ISO string to compare against.
123+
* @returns Number of full days difference.
124+
*/
24125
differenceInDays(dateRight: Dateable): number;
126+
127+
/**
128+
* Get the number of full years between this date and `dateRight`.
129+
* @param dateRight - Date, timestamp or ISO string to compare against.
130+
* @returns Number of full years difference.
131+
*/
25132
differenceInYears(dateRight: Dateable): number;
133+
134+
/**
135+
* Return an ISO date string in `YYYY-MM-DD` format.
136+
* @returns ISO date string (date portion only).
137+
*/
26138
toISODateString(): string;
139+
140+
/**
141+
* Return the epoch milliseconds adjusted to local UTC time.
142+
* This is equivalent to `getTime() - getTimezoneOffset() * 60000`.
143+
* @returns UTC-equivalent timestamp in milliseconds.
144+
*/
27145
utcTime(): number;
28146
}
29147

test/unit/bugfixes/bug-7.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe('incorrect calc', () => {
77
const result = date
88
.addYears(-25)
99
.addMonths(-1)
10-
.differenceInYears(SonicDate.Now);
10+
.differenceInYears(new SonicDate('2025-01-10T09:10:00Z'));
1111

1212
expect(result).toBe(25);
1313
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import assert from 'assert';
2+
import { SonicDate } from 'src/index';
3+
import { differenceInHours } from 'src/methods';
4+
5+
describe(differenceInHours.name, () => {
6+
it('returns the number of full hours between the given dates', () => {
7+
const result = new SonicDate(2014, 8 /* Sep */, 5, 2, 30).differenceInHours(
8+
new SonicDate(2014, 8 /* Sep */, 4, 23, 0),
9+
);
10+
// 3.5 hours -> 3 full hours
11+
assert(result === 3);
12+
});
13+
14+
it('returns a negative number if the time value of the first date is smaller', () => {
15+
const result = new SonicDate(2014, 8 /* Sep */, 4, 23, 0).differenceInHours(
16+
new SonicDate(2014, 8 /* Sep */, 5, 2, 30),
17+
);
18+
assert(result === -3);
19+
});
20+
21+
it('the difference is less than an hour but across calendar hours', () => {
22+
const result = new SonicDate(2014, 8 /* Sep */, 5, 0, 30).differenceInHours(
23+
new SonicDate(2014, 8 /* Sep */, 4, 23, 45),
24+
);
25+
// 0.75 hours -> 0 full hours
26+
assert(result === 0);
27+
});
28+
29+
it('returns NaN if either date is `Invalid Date`', () => {
30+
const a = new SonicDate(NaN);
31+
const b = new SonicDate(2014, 8 /* Sep */, 5);
32+
assert(isNaN(a.differenceInHours(b)));
33+
assert(isNaN(b.differenceInHours(new SonicDate(NaN))));
34+
});
35+
});

test/unit/difference-in-ms.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* eslint-env mocha */
2+
3+
import assert from 'assert';
4+
import { SonicDate } from 'src/index';
5+
import { differenceInMs } from 'src/methods';
6+
7+
describe(differenceInMs.name, () => {
8+
it('returns the millisecond difference between the given dates (no flooring)', () => {
9+
const result = new SonicDate(
10+
2014,
11+
8 /* Sep */,
12+
5,
13+
0,
14+
0,
15+
0,
16+
500,
17+
).differenceInMs(new SonicDate(2014, 8 /* Sep */, 5, 0, 0, 0, 0));
18+
assert(result === 500);
19+
});
20+
21+
it('returns a negative millisecond difference when appropriate', () => {
22+
const result = new SonicDate(
23+
2014,
24+
8 /* Sep */,
25+
5,
26+
0,
27+
0,
28+
0,
29+
0,
30+
).differenceInMs(new SonicDate(2014, 8 /* Sep */, 5, 0, 0, 0, 500));
31+
assert(result === -500);
32+
});
33+
34+
it('returns NaN if either date is `Invalid Date`', () => {
35+
const a = new SonicDate(NaN);
36+
const b = new SonicDate(2014, 8 /* Sep */, 5);
37+
assert(isNaN(a.differenceInMs(b)));
38+
assert(isNaN(b.differenceInMs(new SonicDate(NaN))));
39+
});
40+
});

0 commit comments

Comments
 (0)