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 🙏

© 2026 – Pkg Stats / Ryan Hefner

qrono

v1.5.1

Published

A tiny JavaScript date library with 100+ APIs and strict DST guarantees.

Readme

Qrono — Small. Complete. Deterministic. JavaScript date-time.

A tiny JavaScript date library with 100+ APIs and strict DST guarantees. Designed for single-timezone applications.

MIT License CodeQL NPM version NPM downloads brotli size

import { qrono } from 'qrono'

// UTC-first
const now = qrono().toString() // '2027-01-23T12:34:56:789Z'
// DST overlap (occurs twice) of Europe/London
qrono.context({ localtime: true })
const t = '2019-10-27T01:30:00'
qrono(t) // 01:30 +00:00 Same as JavaScript's `Date`
qrono({ disambiguation: 'earlier' }, t) // 01:30 +00:00
qrono({ disambiguation: 'later' }, t)   // 01:30 +01:00
qrono({ disambiguation: 'reject' }, t)  // throws RangeError

now.plus(0, 1, 10) // +1 month, +10 days
now.startOfMonth()
now.isBetween(qrono('2024-01-01'), qrono('2024-12-31'))
const date = qrono.date('2024-06-15')
date.dayOfYear()   // 167
date.weekOfYear()  // 24
date.endOfMonth()  // 2024-06-30

🌐 Website | 🎨 Design philosophy | 📥 Getting started | 🚀 Quick tour | 🌏 License


Design Philosophy 🎨

🔐 Immutable, Intuitive and Chainable

  • All operations return new instances for safe, predictable data and intuitive API.
  • Covers the majority of common use cases.

🔷 TypeScript Ready

  • Full TypeScript definitions included for type-safe development.
  • Designed to work seamlessly in both server-side and browser-side JavaScript environments.

Minimal and Focused

  • Pure JavaScript with zero dependencies.
  • Lightweight (3.3 kB brotli-compressed), with 100+ APIs in a focused design.

🌍 UTC-first with Local Time Support

🕐 Strict DST Handling

  • Unique DST-aware APIs that no other library provides.
  • Explicit handling of ambiguous daylight saving time transitions through dedicated APIs.

ISO 8601 Compliant

  • Fully compliant with the ISO 8601 standard for reliable date-time exchange and interoperability.

Alternatives

  • Moment.js
    A widely used library that was once the de facto standard for date-time handling in JavaScript. It entered maintenance mode in 2020.
    Its mutable API design can lead to unintended side effects and bugs. Most modern date-time libraries introduced below are designed to be immutable.

  • Luxon
    An immutable, feature-rich library created by the maintainers of Moment.js. It provides comprehensive timezone and formatting support.
    By default, it operates in the system’s local time zone and does not provide strict disambiguation for ambiguous local times.
    Its documentation clearly explains how ambiguous times are handled.

  • Day.js
    A small, Moment.js-compatible library with a large GitHub following, increasingly considered a de facto standard.
    Approximately 3 kB with 30+ core APIs. Timezone, locale support, and additional functionality require plugins.
    Currently preparing a major version upgrade.

  • date-fns
    Provides 200+ pure functions for manipulating JavaScript Date objects. Implemented in TypeScript and fully tree-shakeable.
    Because it builds directly on the native Date object, it inherits limitations such as mutability and zero-based months.

None of these libraries provide dedicated APIs for strict DST transition handling.
Qrono addresses this gap with a balanced and pragmatic approach.

  • The ECMA TC39 Temporal Proposal
    A proposed ECMAScript API that may become a future standard. Temporal (TC39) defines a comprehensive and rigorous date-time model, including numerous classes such as Instant, Duration, and ZonedDateTime, and provides a complete API covering locale handling and the IANA time zone database. While this design ensures correctness and precision across a wide range of use cases, its breadth and strictness can make it heavyweight and difficult to grasp for developers who simply need to handle date and time operations.

In contrast, Qrono focuses on delivering the simplest possible API surface while remaining practical for real-world applications, prioritizing clarity and usability over exhaustive completeness.

Repository Size Comparison

Comparison of repository size

This comparison shows that Qrono stands out for its small codebase among other libraries. Its compact size reflects a strong focus on minimalism and efficiency, making it well suited for situations where bundle size and simplicity are important.

For many of the other libraries, their larger size is due to the fact that a significant portion of the codebase is dedicated to supporting a wide range of locales. Meanwhile, the larger size of date-fns is intentional and not a drawback. It is designed with tree-shaking in mind, so unused functions are removed at build time, and its API is intentionally fine-grained and verbose to provide clarity and flexibility. The size difference therefore represents a difference in design philosophy, not a measure of overall quality.

Getting started 📥

npm  install qrono        # for npm
deno add jsr:@urin/qrono  # for Deno
bunx jsr add @urin/qrono  # for Bun
pnpm add     @urin/qrono  # for pnpm
yarn add     @urin/qrono  # for Yarn
<!-- for Browser -->
<script type="module">
  import { qrono } from './path/to/qrono.js'
</script>
<!-- from UNPKG -->
<script type="module">
  import { qrono } from 'https://unpkg.com/qrono@1/dist/qrono.js'
</script>
// as module
import { qrono } from 'qrono'
// or CommonJS
const { qrono } = require('qrono')

Quick tour 🚀

Visit official website for complete documentation.

Construction

// now
qrono()
// from various types of arguments
qrono('2022-12-31') // => 2022-12-31T00:00:00.000Z
qrono(new Date())
// the following are the same 2022-12-31T15:23:11.321Z
qrono('2022-12-31 15:23:11.321')
qrono(1672500191321)
qrono(2022, 12, 31, 15, 23, 11, 321)
qrono([2022, 12, 31, 15, 23, 11, 321])
qrono({ year: 2022, month: 12, day: 31, hour: 15, minute: 23, second: 11, millisecond: 321 })

Accessor

const time = qrono(2022, 12, 31, 15, 23, 11, 321)
time.year()        // => 2022
time.month()       // => 12
time.day()         // => 31
time.hour()        // => 15
time.minute()      // => 23
time.second()      // => 11
time.millisecond() // => 321

time.second(0) // => returns new Qrono instance

Time zone

// UTC as default
qrono('2022-12-31 15:23:11.321').toString() // => "2022-12-31T15:23:11.321Z"
// set default to local time
qrono.context({ localtime: true })
qrono('2022-12-31 15:23:11.321').toString()     // => "2022-12-31T15:23:11.321-04:00"
qrono('2022-12-31 15:23:11.321').context({ localtime: false }).hour() // => 11 as UTC
qrono('2022-12-31 15:23:11.321').hour()         // => 15 as local time

Conversion

+qrono('2000-01-01')          // => 946,684,800,000 milliseconds from UNIX epoch
const time = qrono('2000-01-02 03:04:05.006')
time.toObject()   // => { year: 2000, month: 1, day: 2, hour: 3, minute: 4, second: 5, millisecond: 6 }
time.toArray()    // => [2000, 1, 2, 3, 4, 5, 6]
time.nativeDate() // => JavaScript native `Date` instance

Calculation

qrono('2000-01-01 01:00:00.000') - qrono('2000-01-01') // => 3,600,000 milliseconds = 1 hour
qrono('2000-01-01 01:00:00.000') < qrono('2000-01-01') // => false
qrono('2000-01-01').plus(7200000).minus(3600000)       // => 2000-01-01T01:00:00.000Z
// In operations using Object, `year`, `month`, and `day` are calculated literally.
// For example, adding one month at the end of a month results in the end of the following month.
// `hour`, `minute`, `second`, and `millisecond` are treated as a duration in calculations.
qrono('2000-01-01').minus({ hour: 1, minute: 30 })     // => 1999-12-31T22:30:00.000Z
qrono('2020-02-29').plus({ year: 1 })                  // => 2021-02-28T00:00:00.000Z
qrono('2021-12-31').minus({ month: 1 })                // => 2021-11-30T00:00:00.000Z

const today = qrono()
const yesterday = today.minus({ day: 1 })
const tomorrow = today.plus({ day: 1 })
today.isBetween(yesterday, tomorrow) // => true

Short-hands

const time = qrono('2000-01-02 03:04:05.006')
time.startOfYear()   // => 2000-01-01T00:00:00.000Z
time.startOfMonth()  // => 2000-01-01T00:00:00.000Z
time.startOfDay()    // => 2000-01-02T00:00:00.000Z
time.startOfHour()   // => 2000-01-02T03:00:00.000Z
time.startOfMinute() // => 2000-01-02T03:04:00.000Z
time.startOfSecond() // => 2000-01-02T03:04:05.000Z
time.dayOfWeek()     // => 7 === qrono.sunday
time.dayOfYear()     // => 2
time.isLeapYear()    // => true
time.daysInMonth()   // => 31
time.daysInYear()    // => 366
// ISO week number. See https://en.wikipedia.org/wiki/ISO_week_date
time.weeksInYear()   // => 52
time.weekOfYear()    // => 52
time.yearOfWeek()    // => 1999
// Daylight saving time stuff that is meaningful in case of local time
const localtime = time.context({ localtime: true })
localtime.hasOffsetChangeInYear()
localtime.isInDst()
localtime.hasOffsetChangeInDay()
localtime.minutesInDay()

QronoDate

qrono.date(...) returns a QronoDate instance with only date information.

Methods of QronoDate are almost compatible with those of Qrono.

qrono.date('2000-01-02').toString()       // => "2000-01-02"
qrono('2000-01-02 23:04:05.006').toDate() // => QronoDate instance 2000-01-02
+qrono.date('2000-01-02')                 // => 10958 days from UNIX epoch

License 🌏

MIT

Copyright (c) 2021 Urin