({
timer = window,
registerTimer,
emitDateChanged,
getDateKey = () => new Date().toDateString(),
getNow = () => new Date(),
intervalMs = 60000,
}: DateChangeDetectionOptions)
| 21 | } |
| 22 | |
| 23 | export function startDateChangeDetection({ |
| 24 | timer = window, |
| 25 | registerTimer, |
| 26 | emitDateChanged, |
| 27 | getDateKey = () => new Date().toDateString(), |
| 28 | getNow = () => new Date(), |
| 29 | intervalMs = 60000, |
| 30 | }: DateChangeDetectionOptions): DateChangeDetectionControls { |
| 31 | let lastKnownDate = getDateKey(); |
| 32 | let midnightTimeout: number | null = null; |
| 33 | |
| 34 | const checkDateChange = (): boolean => { |
| 35 | const currentDate = getDateKey(); |
| 36 | if (currentDate === lastKnownDate) { |
| 37 | return false; |
| 38 | } |
| 39 | |
| 40 | lastKnownDate = currentDate; |
| 41 | emitDateChanged(); |
| 42 | return true; |
| 43 | }; |
| 44 | |
| 45 | const scheduleNextMidnightCheck = (): number => { |
| 46 | const msUntilMidnight = getMillisecondsUntilNextLocalMidnight(getNow()); |
| 47 | |
| 48 | if (midnightTimeout !== null) { |
| 49 | timer.clearTimeout(midnightTimeout); |
| 50 | } |
| 51 | |
| 52 | midnightTimeout = timer.setTimeout(() => { |
| 53 | checkDateChange(); |
| 54 | scheduleNextMidnightCheck(); |
| 55 | }, msUntilMidnight); |
| 56 | |
| 57 | registerTimer(midnightTimeout); |
| 58 | return midnightTimeout; |
| 59 | }; |
| 60 | |
| 61 | const intervalId = timer.setInterval(checkDateChange, intervalMs); |
| 62 | registerTimer(intervalId); |
| 63 | scheduleNextMidnightCheck(); |
| 64 | |
| 65 | return { |
| 66 | checkDateChange, |
| 67 | scheduleNextMidnightCheck, |
| 68 | getLastKnownDate: () => lastKnownDate, |
| 69 | getMidnightTimeout: () => midnightTimeout, |
| 70 | }; |
| 71 | } |
| 72 | |
| 73 | export function getMillisecondsUntilNextLocalMidnight(now: Date): number { |
| 74 | const midnight = new Date(now); |
no test coverage detected