blog/src/utils/useCurrentDate.ts
thislight 4bd975796e
All checks were successful
Build & Depoly / Depoly blog (push) Successful in 1m52s
Move to astro
2025-04-11 21:52:23 +08:00

67 lines
1.5 KiB
TypeScript

import { differenceInMilliseconds } from "date-fns";
import { createRenderEffect, createSignal, onCleanup, untrack } from "solid-js";
import { isServer } from "solid-js/web";
export enum DateRefreshPercision {
seconds = 0,
minutes = 1,
hours,
days,
}
function useCurrentDate(
percision:
| (() => DateRefreshPercision)
| DateRefreshPercision = DateRefreshPercision.minutes,
) {
const [current, setCurrent] = createSignal(new Date());
const updateInterval = () => {
switch (typeof percision === "function" ? percision() : percision) {
case DateRefreshPercision.seconds:
return 1000;
case DateRefreshPercision.minutes:
return 15 * 1000;
case DateRefreshPercision.hours:
return 60 * 1000;
case DateRefreshPercision.days:
return 60 * 60 * 1000;
}
};
let id: undefined | number;
const update = () => setCurrent(new Date());
createRenderEffect(() => {
if (typeof id !== "undefined") {
window.clearInterval(id);
id = undefined;
}
const interval = updateInterval();
const now = new Date();
if (differenceInMilliseconds(now, untrack(current)) <= interval) {
update();
}
id = window.setInterval(update, interval);
});
onCleanup(() => {
if (typeof id !== "undefined") {
window.clearInterval(id);
id = undefined;
}
});
return current;
}
function useCurrentDateServer() {
const now = new Date();
return () => now;
}
export default isServer ? useCurrentDateServer : useCurrentDate;