refactor: calculate rundown duration

This commit is contained in:
Carlos Valente
2024-08-26 09:43:41 +02:00
committed by Carlos Valente
parent d71df886f2
commit 66774321a5
13 changed files with 217 additions and 110 deletions
@@ -8,6 +8,6 @@
* 09:00 - 10:00
* 09:30 - 10:30
*/
export function checkIsNextDay(previousStart: number, timeStart: number, previousDuration?: number): boolean {
export function checkIsNextDay(previousStart: number, timeStart: number, previousDuration: number): boolean {
return previousDuration === 0 ? false : timeStart <= previousStart;
}
@@ -0,0 +1,16 @@
import { checkOverlap } from './checkOverlap';
describe('checkOverlap', () => {
it('should return true if events fully overlap', () => {
expect(checkOverlap(1000, 2000, 1000, 2000)).toBe(true);
});
it('should return true if one of the events is inside the other', () => {
expect(checkOverlap(1000, 2000, 1000, 1000)).toBe(true);
expect(checkOverlap(1000, 2000, 1500, 1750)).toBe(true);
});
it("should return false if events don't overlap", () => {
expect(checkOverlap(1000, 2000, 2000, 3000)).toBe(false);
});
});
@@ -0,0 +1,19 @@
/**
* Check if two Ontime events overlap
* @link https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap
* We use the deconstructed times to facilitate implementation in UI
*/
export function checkOverlap(
previousStart: number,
previousEnd: number,
currentStart: number,
currentEnd: number,
): boolean {
// deal with simple case where the event is later
if (currentStart >= previousEnd) {
return false;
}
// at this point we know there may be an overlap
return Math.max(previousStart, currentStart) - Math.min(previousEnd, currentEnd) <= 0;
}
@@ -0,0 +1,14 @@
import { getTimeFromPrevious } from './getTimeFromPrevious';
describe('getTimeFromPrevious', () => {
it('returns the time elapsed (gap or overlap) from the previous', () => {
const previousStart = 69600000; // 19:20
const previousEnd = 71700000; // 19:55
const previousDuration = 2100000; // 35 minutes
const currentStart = 75600000; // 21:00
const currentEnd = 81000000; // 22:30
const expected = 75600000 - 71700000; // current staart - previousEnd
expect(getTimeFromPrevious(currentStart, currentEnd, previousStart, previousEnd, previousDuration)).toBe(expected);
});
});
@@ -0,0 +1,46 @@
import { checkIsNextDay } from './checkIsNextDay';
import { checkOverlap } from './checkOverlap';
import { dayInMs } from './conversionUtils';
/**
* Utility returns the time elapsed (gap or overlap) from the previous
* It uses deconstructed parameters to simplify implementation in UI
*/
export function getTimeFromPrevious(
currentStart: number,
currentEnd: number,
previousStart?: number,
previousEnd?: number,
previousDuration?: number,
): number {
// there is no previous event
if (previousStart == null || previousEnd == null || previousDuration == null) {
return 0;
}
// event is linked to previous
if (currentStart === previousEnd) {
return 0;
}
// event is the day after
if (checkIsNextDay(previousStart, currentStart, previousDuration)) {
// duration is difference between normalised start and previous end
return currentStart + dayInMs - previousEnd;
}
// event has a gap from previous
if (currentStart > previousEnd) {
return currentStart - previousEnd;
}
// event overlaps with previous
if (checkOverlap(previousStart, previousEnd, currentStart, currentEnd)) {
// duration is the amount of time the current event has over the previous
// this value must be capped at 0
return Math.max(currentEnd - previousEnd, 0);
}
// we need to make sure we return a number, but there are no business cases for this
return 0;
}