Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

datetoken

sonirico12.3kMIT2.1.0TypeScript support: included

Parse relative datetime tokens into date objects

relative, date, token, presets, datetime, parser, now, yesterday, last week

readme

Datetoken 🕰️

npm version GitHub Actions TypeScript Node.js License: MIT Downloads

"Because writing new Date(Date.now() - 24 * 60 * 60 * 1000) to get yesterday's date is for masochists."

Datetoken is a lightweight, zero-dependency utility that interprets human-readable date tokens into JavaScript Date objects. Think of it as a tiny DSL for relative dates that doesn't make you want to cry.

Why Datetoken? 🤔

Let's be honest: JavaScript's Date API is... challenging. Sure, you could memorize the arcane incantations needed to get "last Tuesday" or "end of previous quarter," but wouldn't you rather just write now-w/tue and call it a day?

Datetoken was born from the frustration of writing the same date arithmetic over and over again, especially for:

  • Analytics dashboards (because "last 30 days" is apparently rocket science)
  • Background jobs (scheduled tasks that need to know what "yesterday" means)
  • Date range pickers (where users expect magic, not math)
  • Cache keys (where "data-2024-01-15" is less useful than "data-now-d")

Installation

npm install datetoken

Works with Node.js ≥18. For older versions, you probably have bigger problems to worry about.

Quick Start 🚀

"Show, don't tell" – every programming tutorial ever

import datetoken from 'datetoken';

// The classics
console.log(datetoken('now'));           // Right now (shocking, I know)
console.log(datetoken('now-d/d'));       // Start of yesterday  
console.log(datetoken('now-d@d'));       // End of yesterday

// Business intelligence gold
console.log(datetoken('now-w/bw'));      // Start of last business week
console.log(datetoken('now-1M/M'));      // Start of last month
console.log(datetoken('now/Q'));         // Start of current quarter

// The "wait, that actually works?" category
console.log(datetoken('now-1w+3d-6h'));  // Last week + 3 days - 6 hours
console.log(datetoken('now/Y+Q2/Q2'));   // Start of Q2 this year

Pro tip: If you find yourself calculating dates with raw milliseconds, datetoken is here to judge you silently while solving your problems.

The Tokens Explained 📚

Basic Structure

Every token starts with now because, let's face it, everything is relative to the present moment (how philosophical).

now[±amount][unit][/snap|@snap]

Arithmetic Operations

Add (+) or subtract (-) time units. Math, but make it readable:

datetoken('now-3d');        // 3 days ago
datetoken('now+2w');        // 2 weeks from now  
datetoken('now-1M+5d');     // 1 month ago, plus 5 days
datetoken('now+6h-30m');    // 6 hours and 30 minutes from now

Supported units:

  • s - seconds (because microsecond precision is overrated)
  • m - minutes
  • h - hours
  • d - days
  • w - weeks
  • M - months (capital M, because lowercase is for minutes)
  • Y - years
  • Q - quarters (Q1, Q2, Q3, Q4 also work)

Snap Operations

The real magic happens when you need boundaries. Use / for "start of" and @ for "end of":

datetoken('now/d');         // Start of today (00:00:00)
datetoken('now@d');         // End of today (23:59:59)
datetoken('now-w/w');       // Start of last week
datetoken('now/M');         // Start of this month
datetoken('now-1Y@Y');      // End of last year

Business weeks (bw) are special – they run Monday to Friday, because apparently weekends don't count in corporate America:

datetoken('now/bw');        // Start of current business week (Monday)
datetoken('now@bw');        // End of current business week (Friday)

Common Patterns 💡

"Give a developer a date, they'll code for a day. Teach them datetoken, and they'll never write date arithmetic again."

What You Actually Want The Token Old School Equivalent
Yesterday now-d/d to now-d@d [30 lines of Date() horror]
Last 7 days now-7d to now new Date(Date.now() - 7*24*60*60*1000)
This month now/M to now@M [Stack Overflow intensifies]
Last business week now-w/bw to now-w@bw [Existential crisis]
Q1 this year now/Q1 to now@Q1 [Therapy recommended]
Last month's data now-1M/M to now-1M@M [Career change considered]

Advanced Examples 🎯

Sometimes you need to get creative. Datetoken handles complex chains like a champ:

// Last month's second business week  
datetoken('now-1M/M+w/bw');

// End of Q3 last year
datetoken('now-1Y/Y+Q3@Q3');

// 3 months ago, plus 2 weeks, minus 4 days, snapped to start of week
datetoken('now-3M+2w-4d/w');

// Because someone, somewhere, needs this specific date
datetoken('now-1Y+6M-3w+2d/d');

If you're using chains this complex, you might want to document them. Your future self will thank you.

API Reference 📖

datetoken(token: string, startAt?: Date, clock?: ClockI): Date

Parameters:

  • token - The datetoken string to parse
  • startAt (optional) - Custom starting date (defaults to current time)
  • clock (optional) - Custom clock implementation (for testing, time travel, etc.)

Returns: JavaScript Date object

Throws: InvalidTokenError if the token is malformed

import datetoken, { Token } from 'datetoken';

// Basic usage
const yesterday = datetoken('now-d/d');

// With custom starting point
const customDate = new Date('2024-06-15');
const result = datetoken('now-1w', customDate);

// For testing (inject your own clock)
const mockClock = { getTime: () => new Date('2024-01-01') };
const testDate = datetoken('now+1d', undefined, mockClock);

Module Support 📦

This package is built for the modern world (ES modules) but won't leave you behind:

// ES modules (recommended)
import datetoken from 'datetoken';
import { Token } from 'datetoken';

// CommonJS (if you must)
const datetoken = require('datetoken').default;
const { Token } = require('datetoken');

Performance 🚀

Datetoken is fast enough that you won't notice it, and small enough that you won't care:

  • Zero dependencies (except for date-fns, which you probably already have)
  • ~2KB gzipped (smaller than your average cat GIF)
  • Cached parsing (because we're not monsters)

Browser Support 🌐

Works in any environment that supports ES2022:

  • Node.js ≥18
  • Modern browsers (Chrome 94+, Firefox 93+, Safari 15+)
  • Edge (if that's your thing)

IE support was considered, then we remembered it's 2025.

Testing 🧪

npm test                    # Run tests
npm run test:watch         # Watch mode
npm run test:coverage      # Coverage report

We test extensively because date logic is where bugs go to multiply like rabbits.

Contributing 🤝

Found a bug? Want a feature? Have a better joke for the README?

  1. Fork it (the repository, not the process)
  2. Branch it (git checkout -b feature/amazing-feature)
  3. Test it (npm test)
  4. Commit it (git commit -m 'Add amazing feature')
  5. Push it (git push origin feature/amazing-feature)
  6. PR it (Open a Pull Request)

Known Limitations 🚨

  • Business weeks assume Monday-Friday. If your business runs on Mars time, you're on your own.
  • Quarters follow the standard calendar. Fiscal year weirdness is not supported (yet).
  • Time zones are handled by the underlying Date object. Datetoken doesn't try to be smarter than JavaScript here.

License 📄

MIT License - because sharing is caring, and lawyers are expensive.

Credits 👨‍💻

Built with ❤️ (and a healthy dose of frustration with JavaScript dates) by sonirico.

Special thanks to everyone who's ever had to calculate "last Tuesday" in JavaScript. This one's for you.


"It's not about the destination, it's about the friends we make along the way." – No one, ever, when dealing with date arithmetic.

changelog

Datetoken Change Log

All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning.

[Unreleased]

[1.1.2 - 2021-11-25]

  • Fix(Security): bump minimatch version to >= 3.0.5

[1.1.1 - 2021-11-25]

  • Fix: warning when importing cwd. @danirod

[1.1.0 - 2021-10-03]

  • Feat: Added support for years
  • Feat: Added support for quarters

[1.0.3 - 2021-09-20]

  • Fixed security issues in 'set-value' deps by raising their versions

[1.0.2 - 2020-01-30]

  • Maintenance relase: deps upgrade

[1.0.1 - 2020-03-21]

  • Fixed security issues in 'acorn' and 'minimist' deps by raising their versions

[1.0.0 - 2020-01-24]

  • BREAKING CHANGE: support node versions >= 8.10
  • Dependency upgrades

[0.2.7 - 2019-10-03]

  • Raised intransitive depedencies version to fix security issues

[0.2.5 - 2019-06-10]

  • Raised intransitive depedencies version

[0.2.4 - 2019-01-29]

  • Fixed invalid tokens interpreted as "now"

[0.2.3 - 2019-01-17]

  • Added token JSON representation

[0.2.0 - 2019-01-14]

  • Renamed "tokentodate" to "tokenToDate"
  • Added features:
    • Chainable modifiers after snap modifiers
    • Partial Pratt parser
  • Dropped features:
    • TokenModifier element

[0.1.2 - 2018-11-29]

  • Limit dateutil dependency versions

[0.1.1 - 2018-10-19]

  • Hello world!