@desolint/dates
v0.0.1
Published
Shared date/time utilities for Desol Int. projects
Readme
@desolint/dates
Shared date/time utilities for Desol Int. projects.
Thin, dependency-light wrappers around common date formatting, expiry, and countdown chores, so they behave identically across our apps.
Requirements
- Node.js 22 or newer
Ships both ESM and CJS builds with bundled TypeScript types.
Install
npm install @desolint/datesThat is all — luxon is a regular dependency and comes down with the package.
Why luxon is a dependency, not a peer
Unlike the other @desolint packages, this one takes luxon as a regular
dependency. Those packages declare peers because a duplicated copy genuinely
breaks something — two Redis connection pools, two Mongoose model registries, two
copies of React. luxon has no such shared state: it is a pure formatting library,
so a second copy is at worst a few extra kilobytes, never a bug. Depending on it
directly means you install one package and it just works.
Two functions (getCurrentTimeInSeconds, getFullYear) deliberately avoid luxon
entirely so a consumer importing only those bundles almost nothing.
Quick start
import {formatDate, getFutureDate} from '@desolint/dates';
formatDate({date: '2024-03-15', format: 'dd/MM/yyyy'}); // '15/03/2024'
getFutureDate({days: 7}); // 'Mon, 07 Sep 2026 09:32:07 GMT'Every function takes a single options object, or no argument at all.
API
| Function | What it does |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| getCurrentDateTime() | Current time as an ISO 8601 string, local zone with offset — never Z-normalized. |
| formatDate({date, format?}) | Formats an ISO 8601 string with a format token (default yyyy-MM-dd); null if the date doesn't parse. |
| isValidDate({date}) | Whether a string parses as a valid ISO 8601 date. |
| getCurrentTimeInSeconds() | Current time as whole seconds since the Unix epoch. |
| getFullYear() | The current calendar year. |
| getFutureDate({days?, format?}) | A date days from now (default 30). 'jsDate' returns a Date; 'utcString' (default) and 'iso' return a string. |
| formatToMinutesSeconds({seconds}) | Seconds as a zero-padded m:ss string. |
| calculateSecondsLeft({expiryTime}) | Seconds remaining until an epoch-ms expiry, clamped to 0. |
| convertSecondsToMinutes({seconds}) | Seconds floored down to whole minutes. |
The FutureDateFormat type ('utcString' | 'iso' | 'jsDate') is exported for
annotating a getFutureDate format argument.
Examples
Rendering a date
formatDate returns null rather than throwing, so untrusted values need a
fallback rather than a try:
<span>
{formatDate({date: publishedAt, format: 'd LLL yyyy'}) ?? 'Unknown date'}
</span>Expiry dates for cookies and headers
getFutureDate defaults to 30 days out as an RFC 1123 string, the format
Set-Cookie and Expires want:
document.cookie = `session=${id}; expires=${getFutureDate()}; path=/`;
getFutureDate({days: 1, format: 'iso'}); // '2026-09-01T14:32:07.921+05:00' — JSON, DB columns
getFutureDate({days: 10, format: 'jsDate'}); // Date — for APIs wanting a real DateCountdown timers
const secondsLeft = calculateSecondsLeft({expiryTime}); // epoch ms in, clamped at 0
formatToMinutesSeconds({seconds: secondsLeft}); // '4:59'
formatToMinutesSeconds({seconds: 5}); // '0:05' — seconds are zero-paddedUse formatToMinutesSeconds for display and convertSecondsToMinutes for
arithmetic; the latter floors, so 59 seconds is 0 minutes.
Everything else
getCurrentTimeInSeconds(); // compare against JWT `exp` / `iat` claims
`© ${getFullYear()} Desol Int.`; // '© 2026 Desol Int.'Development
npm install # install dependencies (Husky wires up git hooks)
npm run build # dual CJS + ESM output into dist/cjs and dist/esm
npm run type-check # tsc --noEmit
npm test # type-check + jest
npm run lint # eslintA pre-commit hook runs lint-staged over staged files, and the same lint runs in CI
on every push and PR.
License
MIT © Desolint — see LICENSE.
Free to use, modify and redistribute, commercially or otherwise. Provided "as is", without warranty or liability of any kind.
