npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

waktoo

v1.1.0

Published

A lightweight, modern, Moment-style date-time library with timezone, locale, arithmetic, durations, and relative time. Zero dependencies. Fast. Chainable. Universal.

Downloads

305

Readme

WaktooJS

UTC-First • Lightweight • Chainable Date-Time Library

A fast, modern, dependency-free datetime engine for JavaScript —
with strict UTC parsing, timezone support, locale formatting, durations,
relative time, calendar outputs, and flexible tokens, date range, and age calculation.

“Time made simple. Lightweight. Predictable. Powerful.”

NPM Version License: MIT Bundle Size

See Release notes


Why WaktooJS?

Ideal for applications needing reliable, predictable, and readable date manipulation without heavy dependencies.

Modern JavaScript apps need predictable and readable date operations — not massive libraries. Waktoo focuses on the essentials:

Fast, Lightweight, Zero Dependencies

No overhead. No polyfills. No bloated parsing engine.

UTC-First (Predictable Everywhere)

Your code runs the same on every machine — CI, server, client, container.
No surprise timezone shifts.

Timezone support

Full timezone formatting + abbreviations & offsets.

Modern, Clean, Chainable API

waktoo().tz("Asia/Tokyo").add(1, "day").format("DD MMM YYYY");

Table of Contents


Installation

npm install waktoo

Importing

CommonJS

const waktoo = require("waktoo");

ESM

import waktoo from "waktoo";

Quick Usage

waktoo().format();
// → "2025-12-01T00:00:00.000Z"

waktoo().format("DD MMM YYYY");
// → "16 Nov 2025"

waktoo("2025-12-01").tz("Asia/Jakarta").format("DD MMM YYYY HH:mm Z");
// → "02 Des 2025 07:00 +07:00"

waktoo().locale("id-ID").format("DD MMMM YYYY");
// → "16 November 2025"

waktoo("2025-12-31").fromNow();
// → "in 1 month"

UTC Default Behavior

Waktoo stores everything in strict UTC.

This means:

  • waktoo().hour() → UTC hour
  • waktoo().date() → UTC date
  • waktoo().day() → UTC weekday

This guarantees reproducibility across all machines.


Timezone-Aware Getters

waktoo("2025-12-01T00:00:00Z").tz("Asia/Jakarta").hour();
// → 7

waktoo("2025-12-01T00:00:00Z").tz("America/New_York").date();
// → 30 (previous day)

Any of these reflect the chosen timezone:

  • year()
  • month()
  • date()
  • day()
  • hour()
  • minute()
  • second()

Date Arithmetic

waktoo("2025-01-01").add(3, "days");
waktoo("2025-01-01").add({ months: 2, hours: 5 });

waktoo("2025-01-10").subtract(1, "month");

Diff

const a = waktoo("2025-12-25");
const b = waktoo("2025-12-10");

a.diff(b, "days"); // 15
a.diff(b, "days", true); // 15.0 (float)

Range

Human-readable, localized difference between two dates.

Detailed breakdown

waktoo("2023-01-01").range("2025-03-05");
// → "2 years 2 months 4 days"

Single-unit output

waktoo("2023-01-01").range("2025-01-01", "day");
// → "731 days"

waktoo("2023-01-01").range("2023-01-03", "minute");
// → "2880 minutes"

Localized

waktoo("2023-01-01").locale("id-ID").range("2025-01-01");
// → "2 tahun"

Age

Age is always:

  • absolute
  • localized
  • humanized by default
  • still convertible numerically with .asDays() etc

Basic age

waktoo("2023-01-01").age();
// → "2 years"

Month-based

waktoo("2024-12-01").age();
// → "1 month"

Localized

waktoo("2023-01-01").locale("id-ID").age();
// → "2 tahun"

Conversions

waktoo("2023-01-01").age().asDays();
// → 731

waktoo("2023-01-01").age().asMonths();
// → 24

Duration

waktoo.duration(3, "hours").asMinutes();
// → 180

waktoo.duration({ hours: 2, minutes: 30 }).humanize();
// → "in 2 hours"

Durations support:

  • numeric conversions (.asDays(), .asHours(), etc.)
  • human-readable output (.humanize())
  • suffixless output (.humanize(false))
  • localization (.locale("id-ID"))
  • deterministic normalized formatting (.format())

Duration.format()

.format() always returns a fully normalized breakdown, using localized unit names.

Object-based durations:

waktoo
	.duration({
		years: 2,
		months: 3,
		days: 5,
		hours: 4,
		minutes: 30,
		seconds: 10,
	})
	.format();

// → "2 years 3 months 5 days 4 hours 30 minutes 10 seconds"

Numeric or mixed durations normalize automatically:

waktoo.duration({ minutes: 90 }).format();
// → "1 hour 30 minutes"

Localized:

waktoo.duration({ minutes: 90 }).locale("id-ID").format();
// → "1 jam 30 menit"

Relative Time

waktoo("2025-12-31").fromNow();
// → "in 1 month"

waktoo("2025-12-01").from("2025-11-25");
// → "in 6 days"

Localized:

waktoo().add(1, "hour").locale("id-ID").fromNow();
// → "dalam 1 jam"

waktoo().subtract(2, "hours").locale("id-ID").fromNow();
// → "2 jam yang lalu"

Calendar Output

waktoo("2025-12-31").calendar();
// → "Today at 15:00"
// → "Tomorrow at 11:00"
// → "Yesterday at 22:00"
// → "Sunday at 09:00"
// → "31/12/2025"

Localized:

waktoo("2025-12-31").locale("id-ID").calendar();
// → "Hari ini pukul 15:00"

Token-Based Date Parsing

Supports patterns similar to Moment:

Example:

waktoo("25/12/2025", "DD/MM/YYYY").format("YYYY-MM-DD");
// → "2025-12-25"

waktoo().format("D MMM YYYY HH:mm");
// → "1 January 2025 12:30"

Localized:

waktoo().locale("id-ID").format("D MMM YYYY HH:mm");
// → "1 Januari 2025 12:30"

Strict mode rejects wrong formats:

waktoo("999/99/9999", "DD/MM/YYYY");
// Throws invalid date error

Timezone Formatting

Waktoo supports:

  • Z → "+07:00"
  • ZZ → "+0700"
  • z → "WIB"
  • zzz → "WIB" (long/variant)
waktoo().tz("Asia/Jakarta").format("DD MMM YYYY HH:mm:ss Z z");
// → "16 Nov 2025 23:00:00 +07:00 WIB"

Supported Format Tokens

| Token | Description | | ----- | -------------------- | | YYYY | 4-digit year | | YY | 2-digit year | | MMMM | Month long | | MMM | Month short | | MM | 01–12 | | M | 1–12 | | DD | 01–31 | | D | 1–31 | | dddd | Weekday long | | ddd | Weekday short | | HH | 00–23 | | H | 0–23 | | hh | 01–12 | | h | 1–12 | | mm | 00–59 | | m | 0–59 | | ss | 00–59 | | s | 0–59 | | A | AM/PM | | a | am/pm | | Z | +07:00 | | ZZ | +0700 | | z | timezone abbr | | zzz | long/display TZ abbr |


Supported Timezone Abbreviations

Waktoo includes an expanded global TZ abbreviation map:

| Timezone | Abbrev | | ------------------- | --------- | | Asia/Jakarta | WIB | | Asia/Makassar | WITA | | Asia/Jayapura | WIT | | America/New_York | EST/EDT | | America/Chicago | CST/CDT | | America/Denver | MST/MDT | | America/Los_Angeles | PST/PDT | | America/Phoenix | MST | | America/Toronto | EST | | America/Vancouver | PST | | America/Sao_Paulo | BRT | | Europe/London | GMT/BST | | Europe/Dublin | GMT/IST | | Europe/Paris | CET/CEST | | Europe/Berlin | CET/CEST | | Europe/Madrid | CET/CEST | | Europe/Rome | CET/CEST | | Europe/Moscow | MSK | | Africa/Johannesburg | SAST | | Africa/Cairo | EET | | Africa/Nairobi | EAT | | Asia/Tokyo | JST | | Asia/Seoul | KST | | Asia/Shanghai | CST | | Asia/Hong_Kong | HKT | | Asia/Singapore | SGT | | Asia/Kuala_Lumpur | MYT | | Asia/Bangkok | ICT | | Australia/Sydney | AEST/AEDT | | Australia/Perth | AWST | | Pacific/Auckland | NZST/NZDT |

Fallback behavior:

If a timezone is missing an abbreviation, waktoo uses the last segment of the TZ name (e.g., "Asia/Colombo" → "Colombo").


API Reference Index

Core

  • waktoo(input?)
  • waktoo().format(pattern)
  • waktoo().locale(localeCode)
  • waktoo().tz(timezone)

Getters

  • year()
  • month()
  • date()
  • day()
  • hour()
  • minute()
  • second()

Math

  • add(value, unit)
  • add({ parts })
  • subtract(value, unit)
  • subtract({ parts })
  • diff(otherDate, unit?, float?)

Range

  • range(date2)
  • range(date2, unit)

Age

  • age()
  • .asSeconds()
  • .asMinutes()
  • .asHours()
  • .asDays()
  • .asWeeks()
  • .asMonths()
  • .asYears()

Relative

  • fromNow()
  • from(otherWaktooInstance)

Calendar

  • calendar()

Duration API

  • waktoo.duration(number, unit)
  • waktoo.duration({ parts })
  • .locale(localeCode)
  • .asMilliseconds()
  • .asSeconds()
  • .asMinutes()
  • .asHours()
  • .asDays()
  • .asWeeks()
  • .asMonths()
  • .asYears()
  • .humanize(withSuffix = true)
  • .format()

License

MIT