loony-datetime
v0.2.0
Published
A lightweight, zero-dependency date/time manipulation library with an immutable, chainable API.
Maintainers
Readme
loony-datetime
A lightweight, zero-dependency date/time manipulation library for JavaScript and TypeScript. Immutable API, chainable operations, no external dependencies.
Features
- Zero dependencies — fully self-contained
- Immutable — every operation returns a new instance
- Chainable — compose operations fluently
- TypeScript-first — ships with full type definitions
- ESM + CJS — works in Node.js, bundlers, and modern browsers
Installation
npm install loony-datetimeQuick Start
import DateTime from "loony-datetime";
// Create
const now = DateTime.now();
const today = DateTime.today();
const dt = new DateTime("2024-03-15");
// Manipulate (immutable — original is unchanged)
const nextWeek = today.add(1, "week");
const lastMonth = today.subtract(1, "month");
const startOfDay = today.startOf("day");
// Format
dt.format("MMMM D, YYYY"); // "March 15, 2024"
dt.format("DD/MM/YYYY"); // "15/03/2024"
dt.format("HH:mm:ss"); // "00:00:00"
// Compare
dt.isBefore(now); // true
dt.isAfter("2024-01-01"); // true
dt.isBetween("2024-01-01", "2024-12-31"); // true
// Diff
now.diff(dt, "day"); // days since March 15
dt.toRelative(); // "1 year ago"API Reference
See docs/api.md for the complete method reference.
Static Factories
| Method | Description |
|---|---|
| DateTime.now() | Current date and time |
| DateTime.today() | Today at midnight |
| DateTime.fromISO(str) | Parse an ISO 8601 string |
| DateTime.fromTimestamp(ms) | From millisecond timestamp |
| DateTime.fromUnix(s) | From Unix seconds timestamp |
| DateTime.fromFormat(str, fmt) | Parse with explicit format |
| DateTime.fromObject({ year, month, day, … }) | From date-parts object (month is 1-based) |
| DateTime.fromArray([y, m, d, …]) | From array (month is 1-based) |
Getters
All getters return numbers in human/calendar units:
| Getter | Range | Notes |
|---|---|---|
| .year | full year | — |
| .month | 1–12 | 1 = January |
| .day | 1–31 | — |
| .hour | 0–23 | — |
| .minute | 0–59 | — |
| .second | 0–59 | — |
| .millisecond | 0–999 | — |
| .dayOfWeek | 0–6 | 0 = Sunday |
| .dayOfYear | 1–366 | — |
| .weekNumber | 1–53 | ISO 8601 |
| .quarter | 1–4 | — |
| .timestamp | ms | milliseconds since epoch |
| .isoString | string | ISO 8601 |
Manipulation
dt.add(3, "day") // add 3 days
dt.subtract(1, "month") // subtract 1 month
dt.set({ hour: 9, minute: 0 }) // set specific fields
dt.startOf("month") // first moment of month
dt.endOf("year") // last moment of year
dt.startOf("week") // Sunday 00:00:00
dt.endOf("week") // Saturday 23:59:59.999
dt.clamp(min, max) // constrain to [min, max]
dt.round("hour") // nearest hour
dt.ceil("minute") // ceiling to next minute
dt.floor("day") // floor to start of day
dt.addBusinessDays(5) // skip weekendsFormatting
dt.format("YYYY-MM-DD") // "2024-03-15"
dt.format("MMMM D, YYYY") // "March 15, 2024"
dt.format("ddd, MMM D") // "Fri, Mar 15"
dt.format("h:mm A") // "2:30 PM"
dt.format("HH:mm:ss.SSS") // "14:30:45.500"
dt.toRelative() // "in 3 days" / "2 hours ago"
dt.toCalendar() // "Today" / "Yesterday" / "Next week"
dt.toOrdinalString() // "15th"
dt.toISOWeekDate() // "2024-W11-5"Format Tokens
| Token | Output | Example |
|---|---|---|
| YYYY | 4-digit year | 2024 |
| YY | 2-digit year | 24 |
| MMMM | Full month name | March |
| MMM | Short month name | Mar |
| MM | Padded month | 03 |
| M | Month number | 3 |
| DD | Padded day | 05 |
| D | Day number | 5 |
| dddd | Full weekday name | Friday |
| ddd | Short weekday name | Fri |
| HH | 24h hour padded | 14 |
| H | 24h hour | 14 |
| hh | 12h hour padded | 02 |
| h | 12h hour | 2 |
| mm | Minutes padded | 05 |
| m | Minutes | 5 |
| ss | Seconds padded | 09 |
| s | Seconds | 9 |
| SSS | Milliseconds padded | 500 |
| A | AM/PM | PM |
| a | am/pm | pm |
Examples
// Scheduling
const meeting = DateTime.today().add(2, "day").set({ hour: 14, minute: 30 });
console.log(meeting.format("dddd, MMMM D [at] h:mm A"));
// Business days
const deadline = DateTime.today().addBusinessDays(10);
// Date ranges
const range = new DateTime("2024-01-01").rangeTo("2024-01-07");
// → [DateTime("2024-01-01"), …, DateTime("2024-01-07")]
// Fiscal quarters
const q = DateTime.today().fiscalQuarter(4); // April fiscal start
// Clamping
const clamped = someDate.clamp("2024-01-01", "2024-12-31");See docs/examples.md for real-world patterns.
License
ISC
