Skip to content

amirhossein693/tiny-date-ranger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tiny-date-ranger

⚡️ A zero-dependency JavaScript utility that parses natural language date ranges such as "last 7 days", "this month", or "Q3 2024" into exact JavaScript Date objects.
TypeScript-first, locale-aware (en + fa), deterministic, and only ~1 KB gzipped.

npm version npm downloads License: MIT


🚀 Quick Start

Installation

npm install tiny-date-ranger
# or
yarn add tiny-date-ranger
# or
pnpm add tiny-date-ranger

Usage

import { parseRange } from "tiny-date-ranger";

const { start, end, label } = parseRange("last 7 days");

console.log({ start, end, label });
// → {
//     start: 2025-10-26T00:00:00.000Z,
//     end:   2025-11-02T23:59:59.999Z,
//     label: "Last 7 days"
//   }

📖 API

parseRange(input, options?)

Parses a natural language date range string and returns a range object.

parseRange(
  input: string,
  options?: {
    now?: Date;                     // optional reference date (useful for testing)
    weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6; // default: 1 (Monday)
    locale?: "en" | "fa";           // default: "en"
  }
): {
  start: Date;
  end: Date;
  label: string;
};

Parameters:

  • input (string): The natural language date range to parse
  • options (optional object):
    • now (Date): Reference date for relative calculations (defaults to current date/time)
    • weekStartsOn (0-6): First day of the week (0 = Sunday, 1 = Monday, etc.). Default: 1
    • locale ("en" | "fa"): Language for input parsing. Default: "en"

Returns:

  • start (Date): Start of the range (time set to 00:00:00.000)
  • end (Date): End of the range (time set to 23:59:59.999)
  • label (string): Human-readable label for the range

📅 Supported Inputs

English Input Persian Alias (fa) Description
today امروز Current day
yesterday دیروز Previous day
last 7 days ۷ روز گذشته, هفت روز گذشته Last 7 days including today
last 30 days Last 30 days including today
this week این هفته Current calendar week
last week هفته قبل Previous calendar week
this month این ماه Current month
last month ماه قبل Previous month
this quarter این فصل Current quarter (Q1-Q4)
Q1 2025Q4 2025 Specific quarter of a year
ytd Year-to-date (Jan 1 → today)

Note: All results are returned as local Date objects, with time clamped between 00:00:00.000 and 23:59:59.999.


💡 Examples

Basic Usage

import { parseRange } from "tiny-date-ranger";

// Today and yesterday
parseRange("today");
// → { start: 2025-11-02T00:00:00.000Z, end: 2025-11-02T23:59:59.999Z, label: "Today" }

parseRange("yesterday");
// → { start: 2025-11-01T00:00:00.000Z, end: 2025-11-01T23:59:59.999Z, label: "Yesterday" }

// Rolling periods
parseRange("last 7 days");
// → Last 7 days including today

parseRange("last 30 days");
// → Last 30 days including today

Weekly Ranges

// Week starting on Monday (default)
parseRange("this week");

// Week starting on Sunday
parseRange("this week", { weekStartsOn: 0 });

// Last week
parseRange("last week");

Monthly & Quarterly

// Current month
parseRange("this month");
// → Full current month (1st 00:00 to last day 23:59:59.999)

// Previous month
parseRange("last month");

// Quarters
parseRange("this quarter");
parseRange("Q1 2024");
parseRange("Q3 2024");
// → { start: 2024-07-01T00:00:00.000Z, end: 2024-09-30T23:59:59.999Z, label: "Q3 2024" }

Year-to-Date

parseRange("ytd");
// → From January 1st of current year to today

Persian (فارسی)

// Set locale to "fa"
parseRange("امروز", { locale: "fa" });
parseRange("این هفته", { locale: "fa" });
parseRange("ماه قبل", { locale: "fa" });
parseRange("۷ روز گذشته", { locale: "fa" });

Deterministic Testing

// Inject a fixed date for testing
const fixedDate = new Date("2025-06-15T12:00:00Z");
const result = parseRange("last 7 days", { now: fixedDate });

console.log(result.start.toISOString());
// → Always returns 2025-06-09T00:00:00.000Z (deterministic)

✨ Features

  • Zero dependencies — ~1 KB gzipped, no bloat
  • 🧠 Locale aware — Built-in support for English (en) and Persian (fa)
  • 🧪 Deterministic — Injectable now parameter for predictable tests
  • ⚙️ TypeScript-first — Full type definitions included
  • 🌍 Universal — Works in Node.js, browsers, and edge runtimes
  • 📦 Modern exports — ESM + CJS dual format
  • 🕓 Future-proof — Design ready for upcoming Temporal API
  • 🔧 Configurable — Customize week start day
  • 🚀 Tree-shakeable — Only bundle what you use

🛠️ Use Cases

Perfect for:

  • 📊 Analytics dashboards
  • 📈 Data visualization tools
  • 🗓️ Calendar and scheduling apps
  • 📉 Reporting systems
  • 🔍 Search filters with date ranges
  • 📱 React/Vue/Angular date pickers
  • ⚡ Next.js/Remix/SvelteKit apps

🏗️ How It Works

Understanding the library's architecture (great for contributors):

Flow Overview

Input String → Locale Mapping → Switch Case → Helper Functions → Date Range

1. Locale Mapping

EN Map: "last 7 days"  "last_7"
FA Map: "۷ روز گذشته"  "last_7"

2. Core Logic (parseRange)

parseRange("last 7 days", options)
  
  1. Normalize input (trim, lowercase)
  2. Look up in locale maps (EN or FA)
  3. Switch on the normalized key
  4. Calculate start/end using helper functions
  5. Return { start, end, label }

3. Helper Functions

floorDay()      // Set to 00:00:00.000
ceilDay()       // Set to 23:59:59.999
startOfWeek()   // Calculate week start based on weekStartsOn
endOfWeek()     // Calculate week end
startOfMonth()  // First day of month
endOfMonth()    // Last day of month
startOfQuarter()// First day of quarter (Q1-Q4)
endOfQuarter()  // Last day of quarter

4. Special Cases

  • Quarters: Regex /^q([1-4])\s*(\d{4})$/ for "Q3 2024"
  • YTD: From Jan 1 of current year to today
  • Rolling periods: "last 7 days" includes today (goes back 6 days)

Example Walkthrough

parseRange("last 7 days", { now: new Date("2025-06-15") })

Step 1: Normalize  "last 7 days"
Step 2: EN Map lookup  "last_7"
Step 3: Switch case "last_7"
Step 4: Calculate:
  - end = ceilDay(2025-06-15)  2025-06-15T23:59:59.999Z
  - start = floorDay(2025-06-15) - 6 days  2025-06-09T00:00:00.000Z
Step 5: Return { start, end, label: "Last 7 days" }

🧪 Testing

The library includes comprehensive test coverage using Vitest:

pnpm test
# or
npm test

Run tests in watch mode:

pnpm test:watch

Key testing features:

  • Deterministic tests using the now option
  • All supported inputs covered
  • Edge cases (quarter boundaries, month/week transitions)
  • Locale switching (en/fa)

📝 License

MIT © amirhossein693


🤝 Contributing

Contributions, issues, and feature requests are welcome!

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📦 Related Projects

Looking for more date utilities?

  • date-fns — Modern JavaScript date utility library
  • dayjs — 2KB immutable date library
  • luxon — Powerful date/time library

Made with ❤️ for the JavaScript community

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors