js-date-helpers
v1.0.5
Published
A lightweight collection of JavaScript/TypeScript utility functions for formatting and manipulating dates.
Keywords
Readme
js-date-helpers
A lightweight, zero-dependency JavaScript/TypeScript date library. A drop-in alternative to dayjs with a chainable API, full TypeScript support, and built-in relative time, UTC, and comparison features.
Table of Contents
- Installation
- Quick Start
- Chainable API (dayjs-compatible)
- Standalone Utility Functions
- Advanced Usage
- Migrating from dayjs
- TypeScript
- Features
- Browser Support
Installation
npm
npm install js-date-helpersyarn
yarn add js-date-helperspnpm
pnpm add js-date-helpersQuick Start
Chainable API (recommended)
import dateHelper from "js-date-helpers";
// Create an instance
const now = dateHelper();
const date = dateHelper("2025-08-25");
// Format
date.format("YYYY-MM-DD"); // "2025-08-25"
date.format("ddd, MMM D, YYYY"); // "Mon, Aug 25, 2025"
date.format("hh:mm A"); // "12:00 AM"
// Manipulate (immutable — always returns a new instance)
date.add(2, "month").format("YYYY-MM-DD"); // "2025-10-25"
date.subtract(1, "year").format("YYYY"); // "2024"
date.startOf("month").format("YYYY-MM-DD"); // "2025-08-01"
// Compare
date.isBefore("2025-12-31"); // true
date.isAfter("2025-01-01"); // true
date.diff("2025-01-01", "month"); // 7
// Relative time
date.fromNow(); // "a year ago"
date.from("2025-01-01"); // "in 8 months"
// Chain everything
dateHelper("2025-01-15")
.add(1, "month")
.subtract(5, "day")
.startOf("day")
.format("YYYY-MM-DD HH:mm:ss"); // "2025-02-10 00:00:00"Standalone Functions
import {
formatDate,
formatDateTime,
formatFriendly,
addMonths,
getAge,
timeAgo,
format,
} from "js-date-helpers";
formatDate(); // "2025-12-15"
formatDateTime(); // "2025-12-15 14:30"
formatFriendly(); // "Monday, Dec 15, 2025"
addMonths(new Date(), 2); // 2 months later
getAge("1990-05-15"); // age in years
timeAgo(new Date(Date.now() - 3600000)); // "1 hour ago"
format(new Date(), "dddd, MMMM D, YYYY"); // "Monday, December 15, 2025"Chainable API (dayjs-compatible)
The dateHelper function returns an immutable DateHelper instance with a chainable API that mirrors dayjs.
Creating Instances
import dateHelper from "js-date-helpers";
dateHelper(); // Current date and time
dateHelper("2025-08-25"); // From ISO string
dateHelper("2025-08-25T13:45:06"); // From datetime string
dateHelper(1756091106123); // From Unix timestamp (milliseconds)
dateHelper(new Date()); // From native Date object
dateHelper(dateHelper()); // Clone from another DateHelper
dateHelper.unix(1756091106); // From Unix timestamp (seconds)
dateHelper.utc("2025-08-25"); // Create in UTC mode
dateHelper(null); // Invalid date (isValid() → false)Display / Output
const d = dateHelper("2025-08-25T13:45:06.123");
d.format(); // "2025-08-25T13:45:06+05:45" (default)
d.format("YYYY-MM-DD"); // "2025-08-25"
d.format("ddd, MMM D, YYYY"); // "Mon, Aug 25, 2025"
d.format("hh:mm A"); // "01:45 PM"
d.format("HH:mm:ss.SSS"); // "13:45:06.123"
d.toString(); // Native Date string
d.toISOString(); // "2025-08-25T08:00:06.123Z"
d.toJSON(); // "2025-08-25T08:00:06.123Z"
d.toDate(); // Native Date object
d.valueOf(); // Unix timestamp in ms
d.unix(); // Unix timestamp in secondsSee the Format Tokens table for all supported tokens.
Get / Set
All setters are immutable and return a new DateHelper instance.
const d = dateHelper("2025-08-25T13:45:06.123");
// Getters
d.year(); // 2025
d.month(); // 7 (0-indexed, August)
d.date(); // 25 (day of month)
d.day(); // 1 (day of week, 0=Sun)
d.hour(); // 13
d.minute(); // 45
d.second(); // 6
d.millisecond(); // 123
// Generic getter
d.get("year"); // 2025
d.get("M"); // 7 (shorthand works too)
// Setters (return new instance)
d.year(2030); // DateHelper → 2030-08-25
d.month(0); // DateHelper → 2025-01-25
d.date(1); // DateHelper → 2025-08-01
d.hour(0); // DateHelper → 2025-08-25 00:45:06
// Generic setter
d.set("year", 2030); // DateHelper → 2030-08-25Manipulation
All manipulation methods return a new DateHelper instance (immutable).
.add(value, unit)
const d = dateHelper("2025-08-25");
d.add(1, "year"); // 2026-08-25
d.add(2, "month"); // 2025-10-25
d.add(1, "week"); // 2025-09-01
d.add(7, "day"); // 2025-09-01
d.add(3, "hour"); // 2025-08-25 03:00:00
d.add(30, "minute"); // 2025-08-25 00:30:00
d.add(10, "second"); // 2025-08-25 00:00:10
// Shorthands work too
d.add(1, "y"); // year
d.add(2, "M"); // month
d.add(1, "w"); // week
d.add(1, "d"); // day
d.add(1, "h"); // hour
d.add(1, "m"); // minute
d.add(1, "s"); // second
d.add(100, "ms"); // millisecond.subtract(value, unit)
d.subtract(1, "year"); // 2024-08-25
d.subtract(3, "month"); // 2025-05-25.startOf(unit) / .endOf(unit)
const d = dateHelper("2025-08-25T13:45:06.123");
d.startOf("year"); // 2025-01-01 00:00:00.000
d.startOf("month"); // 2025-08-01 00:00:00.000
d.startOf("week"); // 2025-08-25 00:00:00.000 (Monday)
d.startOf("day"); // 2025-08-25 00:00:00.000
d.startOf("hour"); // 2025-08-25 13:00:00.000
d.startOf("minute"); // 2025-08-25 13:45:00.000
d.startOf("second"); // 2025-08-25 13:45:06.000
d.endOf("year"); // 2025-12-31 23:59:59.999
d.endOf("month"); // 2025-08-31 23:59:59.999
d.endOf("day"); // 2025-08-25 23:59:59.999.clone()
const original = dateHelper("2025-08-25");
const copy = original.clone();Comparison / Query
.isBefore(date, unit?) / .isAfter(date, unit?) / .isSame(date, unit?)
const d = dateHelper("2025-06-15");
d.isBefore("2025-12-31"); // true
d.isAfter("2025-01-01"); // true
d.isSame("2025-06-15"); // true
// Compare with unit granularity
d.isSame("2025-06-01", "month"); // true (same month)
d.isSame("2025-01-01", "year"); // true (same year)
d.isBefore("2025-07-01", "month"); // true.isBetween(start, end, unit?, inclusivity?)
const d = dateHelper("2025-06-15");
d.isBetween("2025-01-01", "2025-12-31"); // true (exclusive)
d.isBetween("2025-06-15", "2025-12-31", undefined, "[]"); // true (inclusive)
d.isBetween("2025-06-15", "2025-12-31", undefined, "()"); // false (exclusive)
d.isBetween("2025-01-01", "2025-12-31", "month", "[)"); // trueInclusivity options: "()" (default, exclusive), "[]" (inclusive), "[)", "(]"
.isValid()
dateHelper("2025-08-25").isValid(); // true
dateHelper("invalid").isValid(); // false
dateHelper(null).isValid(); // false.isLeapYear()
dateHelper("2024-01-01").isLeapYear(); // true
dateHelper("2025-01-01").isLeapYear(); // false.daysInMonth()
dateHelper("2025-02-01").daysInMonth(); // 28
dateHelper("2024-02-01").daysInMonth(); // 29
dateHelper("2025-08-01").daysInMonth(); // 31Diff
.diff(date, unit?, float?)
Returns the difference between two dates. Default unit is milliseconds.
const a = dateHelper("2025-01-01");
const b = dateHelper("2025-06-15");
b.diff(a, "month"); // 5
b.diff(a, "day"); // 165
b.diff(a, "hour"); // 3960
b.diff(a, "week"); // 23
b.diff(a); // 14256000000 (milliseconds)
// Floating point result
b.diff(a, "month", true); // 5.451... (precise)Relative Time
Built-in relative time support (no plugin needed, unlike dayjs).
.fromNow(withoutSuffix?)
dateHelper("2025-01-01").fromNow(); // "a year ago"
dateHelper("2025-01-01").fromNow(true); // "a year" (no suffix)
dateHelper(Date.now() - 3600000).fromNow(); // "an hour ago"
dateHelper(Date.now() - 30000).fromNow(); // "a few seconds ago"
dateHelper(Date.now() + 86400000).fromNow(); // "in a day".from(date, withoutSuffix?)
dateHelper("2025-06-01").from("2025-01-01"); // "in 5 months"
dateHelper("2025-01-01").from("2025-06-01"); // "5 months ago".toNow(withoutSuffix?) / .to(date, withoutSuffix?)
dateHelper("2025-01-01").toNow(); // "in a year"
dateHelper("2025-01-01").to("2025-06-01"); // "in 5 months"
dateHelper("2025-06-01").to("2025-01-01"); // "5 months ago"Relative time thresholds:
| Range | Output | | -------------- | --------------- | | 0 - 44 seconds | a few seconds | | 45 - 89 seconds | a minute | | 90s - 44 minutes | X minutes | | 45 - 89 minutes | an hour | | 90m - 21 hours | X hours | | 22 - 35 hours | a day | | 36h - 25 days | X days | | 26 - 45 days | a month | | 46 - 319 days | X months | | 320 - 547 days | a year | | 548+ days | X years |
UTC
// Create in UTC mode
const utcDate = dateHelper.utc("2025-08-25T13:45:00Z");
utcDate.hour(); // 13
utcDate.isUTC(); // true
utcDate.utcOffset(); // 0
// Convert between UTC and local
const localDate = utcDate.local();
localDate.isUTC(); // false
const backToUtc = localDate.utc();
backToUtc.isUTC(); // true
// Any instance can switch to UTC
dateHelper("2025-08-25").utc().hour(); // UTC hourStatic Methods
import dateHelper from "js-date-helpers";
// Create from Unix timestamp (seconds)
dateHelper.unix(1756091106);
// Create in UTC mode
dateHelper.utc("2025-08-25");
// Type checking
dateHelper.isDayjs(dateHelper()); // true (dayjs-compatible alias)
dateHelper.isDateHelper(dateHelper()); // true
// Min / Max
const dates = [
dateHelper("2025-03-01"),
dateHelper("2025-01-01"),
dateHelper("2025-12-01"),
];
dateHelper.min(dates).format("YYYY-MM-DD"); // "2025-01-01"
dateHelper.max(dates).format("YYYY-MM-DD"); // "2025-12-01"
// Also accepts spread arguments
dateHelper.min(dateHelper("2025-01-01"), dateHelper("2025-06-01"));
dateHelper.max(dateHelper("2025-01-01"), dateHelper("2025-06-01"));
// Set global locale
dateHelper.locale(myCustomLocale);Units
All methods that accept a unit support both full names, plural forms, and shorthands:
| Unit | Shorthand | Description |
| ------------- | --------- | ------------------ |
| year | y | Year |
| month | M | Month |
| week | w | Week |
| day | d | Day of week |
| date | D | Day of month |
| hour | h | Hour |
| minute | m | Minute |
| second | s | Second |
| millisecond | ms | Millisecond |
Plural forms also work: "years", "months", "days", etc.
Standalone Utility Functions
These standalone functions are also available for quick, one-off operations without creating a DateHelper instance.
Formatting Functions
formatDate(date?)
Format a date as YYYY-MM-DD.
import { formatDate } from "js-date-helpers";
formatDate(); // "2025-12-15"
formatDate(new Date("2025-08-25")); // "2025-08-25"formatDateTime(date?)
Format a date with time as YYYY-MM-DD HH:mm.
import { formatDateTime } from "js-date-helpers";
formatDateTime(); // "2025-12-15 14:30"
formatDateTime(new Date("2025-08-25T13:45:00")); // "2025-08-25 13:45"formatFriendly(date?)
Format a date in a human-readable format.
import { formatFriendly } from "js-date-helpers";
formatFriendly(); // "Monday, Dec 15, 2025"
formatFriendly(new Date("2025-08-25")); // "Monday, Aug 25, 2025"format(input?, mask?, options?)
Advanced date formatting with custom masks and locale support.
import { format } from "js-date-helpers";
const d = new Date("2025-08-25T13:45:06.123");
format(d, "YYYY-MM-DD"); // "2025-08-25"
format(d, "ddd, MMM D, YYYY"); // "Mon, Aug 25, 2025"
format(d, "YYYY-[W]WW-E"); // "2025-W35-1"
format(d, "hh:mm A"); // "01:45 PM"
format(d, "HH:mm:ss.SSS"); // "13:45:06.123"
format(d, "Qo [quarter], DDDD [DoY]"); // "3rd quarter, 237 DoY"Format Tokens
| Token | Description | Example |
| ----------- | ------------------------------- | -------------------- |
| YYYY | 4-digit year | 2025 |
| YY | 2-digit year | 25 |
| GGGG | ISO week-year | 2025 |
| M | Month without padding | 1-12 |
| MM | Month with padding | 01-12 |
| MMM | Short month name | Jan, Feb... |
| MMMM | Full month name | January, February... |
| D | Day without padding | 1-31 |
| DD | Day with padding | 01-31 |
| Do | Ordinal day | 1st, 2nd, 3rd... |
| ddd | Short weekday | Mon, Tue... |
| dddd | Full weekday | Monday, Tuesday... |
| DDD | Day of year without padding | 1-366 |
| DDDD | Day of year with padding | 001-366 |
| H | Hour (24h) without padding | 0-23 |
| HH | Hour (24h) with padding | 00-23 |
| h | Hour (12h) without padding | 1-12 |
| hh | Hour (12h) with padding | 01-12 |
| m | Minute without padding | 0-59 |
| mm | Minute with padding | 00-59 |
| s | Second without padding | 0-59 |
| ss | Second with padding | 00-59 |
| S | Millisecond (1 digit) | 0-9 |
| SS | Millisecond (2 digits) | 00-99 |
| SSS | Millisecond (3 digits) | 000-999 |
| A | Meridiem (uppercase) | AM, PM |
| a | Meridiem (lowercase) | am, pm |
| Q | Quarter without padding | 1-4 |
| Qo | Quarter ordinal | 1st, 2nd, 3rd, 4th |
| W | ISO week number without padding | 1-53 |
| WW | ISO week number with padding | 01-53 |
| E | ISO weekday | 1-7 (Mon-Sun) |
| Z | Timezone offset | +05:45, -08:00 |
| ZZ | Timezone offset (no colon) | +0545, -0800 |
| X | Unix timestamp (seconds) | 1756091106 |
| x | Unix timestamp (milliseconds) | 1756091106123 |
| [literal] | Escape literal characters | [UTC] → UTC |
Date Manipulation Functions
addMonths(date?, months?)
import { addMonths } from "js-date-helpers";
addMonths(new Date("2025-08-15"), 2); // Oct 15, 2025
addMonths(new Date("2025-08-15"), -3); // May 15, 2025addYears(date?, years?)
import { addYears } from "js-date-helpers";
addYears(new Date("2025-08-15"), 5); // Aug 15, 2030
addYears(new Date("2025-08-15"), -1); // Aug 15, 2024startOfMonth(date?) / endOfMonth(date?)
import { startOfMonth, endOfMonth } from "js-date-helpers";
startOfMonth(new Date("2025-08-25")); // Aug 1, 2025
endOfMonth(new Date("2025-08-25")); // Aug 31, 2025Date Comparison Functions
isSameDay(date1, date2) / isSameMonth(date1, date2)
import { isSameDay, isSameMonth } from "js-date-helpers";
isSameDay(new Date("2025-08-25T10:00"), new Date("2025-08-25T14:30")); // true
isSameDay(new Date("2025-08-25"), new Date("2025-08-26")); // false
isSameMonth(new Date("2025-08-25"), new Date("2025-08-15")); // true
isSameMonth(new Date("2025-08-25"), new Date("2025-09-25")); // falseDate Information Functions
daysInMonth(date?)
import { daysInMonth } from "js-date-helpers";
daysInMonth(new Date("2025-02-15")); // 28
daysInMonth(new Date("2024-02-15")); // 29getAge(dob)
import { getAge } from "js-date-helpers";
getAge("1990-05-15"); // 35 (as of 2025)
getAge(new Date("1990-05-15")); // 35getWeekNumber(date?)
import { getWeekNumber } from "js-date-helpers";
getWeekNumber(new Date("2025-08-25")); // 35
getWeekNumber(new Date("2025-01-01")); // 1getQuarter(date?)
import { getQuarter } from "js-date-helpers";
getQuarter(new Date("2025-08-25")); // 3
getQuarter(new Date("2025-01-15")); // 1Utility Functions
timeAgo(date)
import { timeAgo } from "js-date-helpers";
timeAgo(new Date(Date.now() - 30000)); // "just now"
timeAgo(new Date(Date.now() - 120000)); // "2 minutes ago"
timeAgo(new Date(Date.now() - 3600000)); // "1 hour ago"
timeAgo(new Date(Date.now() - 86400000)); // "1 day ago"toISODate(date?)
import { toISODate } from "js-date-helpers";
toISODate(new Date("2025-08-25T13:45:06.123"));
// "2025-08-25T13:45:06.123Z"Advanced Usage
Custom Format Masks
import { format } from "js-date-helpers";
const date = new Date("2025-12-15T14:30:45");
format(date, "DD/MM/YYYY"); // "15/12/2025"
format(date, "GGGG-[W]WW-E"); // "2025-W50-1"
format(date, "YYYY-MM-DD HH:mm:ss.SSS"); // "2025-12-15 14:30:45.000"
format(date, "YYYY_MM_DD__HH-mm-ss"); // "2025_12_15__14-30-45"
format(date, "[Date:] YYYY-MM-DD [at] HH:mm [UTC]Z"); // "Date: 2025-12-15 at 14:30 UTC+05:45"The same tokens work with the chainable API:
import dateHelper from "js-date-helpers";
dateHelper("2025-12-15T14:30:45").format("DD/MM/YYYY"); // "15/12/2025"Locale Support
Both the standalone format() function and the chainable API support custom locales:
import dateHelper, { format } from "js-date-helpers";
const customLocale = {
months: ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
weekdays: ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"],
weekdaysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
meridiem: (h, m, isLower) => (h < 12 ? (isLower ? "am" : "AM") : (isLower ? "pm" : "PM")),
ordinal: (n) => {
const suffix = ["st", "nd", "rd"][((((n + 90) % 100) - 10) % 10) - 1] || "th";
return n + suffix;
},
};
// Standalone
format(new Date("2025-08-25T13:45:00"), "dddd, MMMM Do, YYYY [at] hh:mm A", { locale: customLocale });
// "Monday, August 25th, 2025 at 01:45 PM"
// Chainable — per-instance locale
dateHelper("2025-08-25").locale(customLocale).format("dddd, MMMM Do, YYYY");
// "Monday, August 25th, 2025"
// Chainable — global locale
dateHelper.locale(customLocale);
dateHelper("2025-08-25").format("MMMM YYYY"); // "August 2025"Migrating from dayjs
js-date-helpers provides a chainable dateHelper() function that mirrors the dayjs API. Here's how to migrate:
// Before (dayjs)
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import isBetween from "dayjs/plugin/isBetween";
import isLeapYear from "dayjs/plugin/isLeapYear";
import minMax from "dayjs/plugin/minMax";
import utc from "dayjs/plugin/utc";
dayjs.extend(relativeTime);
dayjs.extend(isBetween);
dayjs.extend(isLeapYear);
dayjs.extend(minMax);
dayjs.extend(utc);
dayjs("2025-08-25").add(1, "month").format("YYYY-MM-DD");
dayjs("2025-08-25").fromNow();
dayjs("2025-08-25").isBetween("2025-01-01", "2025-12-31");
dayjs.min(dayjs("2025-01-01"), dayjs("2025-06-01"));
// After (js-date-helpers) — no plugins needed!
import dateHelper from "js-date-helpers";
dateHelper("2025-08-25").add(1, "month").format("YYYY-MM-DD");
dateHelper("2025-08-25").fromNow();
dateHelper("2025-08-25").isBetween("2025-01-01", "2025-12-31");
dateHelper.min(dateHelper("2025-01-01"), dateHelper("2025-06-01"));Key differences:
- No plugin system — all features are built-in (relative time, UTC, isBetween, isLeapYear, min/max)
- The factory function is called
dateHelperinstead ofdayjs(or alias it:const dayjs = dateHelper) isDayjs()works as a compatibility alias forisDateHelper()
TypeScript
Full TypeScript support with exported types:
import dateHelper, { DateHelper, Locale, FormatOptions, DateInput, Unit } from "js-date-helpers";
// All types are available
const d: DateHelper = dateHelper("2025-08-25");
const unit: Unit = "month";
const locale: Locale = {
months: [/* ... */],
monthsShort: [/* ... */],
weekdays: [/* ... */],
weekdaysShort: [/* ... */],
meridiem: (h, m, isLower) => isLower ? "am" : "AM",
ordinal: (n) => `${n}th`,
};
const options: FormatOptions = { locale, utc: true };Features
- Zero Dependencies — No external packages required
- TypeScript First — Full type definitions included
- Immutable — All manipulation methods return new instances
- Chainable API — dayjs-compatible fluent interface
- Built-in Relative Time —
.fromNow(),.from(),.toNow(),.to()without plugins - Built-in UTC —
.utc(),.local(),.isUTC()without plugins - Built-in Comparisons —
.isBefore(),.isAfter(),.isSame(),.isBetween()without plugins - 30+ Format Tokens — Comprehensive date formatting
- Locale Support — Format dates in any language
- Lightweight — Minimal bundle size
Browser Support
| Browser | Support | | ------- | -------------------- | | Chrome | Latest | | Firefox | Latest | | Safari | Latest | | Edge | Latest | | Node.js | 10+ |
Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue for bugs and feature requests.
Authors:
- Sushan
- Niroj
- Bhupendra
- Nikhil
License
This project is licensed under the ISC License - see the LICENSE file for details.
Support
For npm package information, visit npm.
