Chronos-ts — named after the Greek god of time — is a comprehensive TypeScript library for date and time manipulation. Version 2.0 is a complete rewrite inspired by Carbon PHP, bringing modern, intuitive date handling to TypeScript and JavaScript.
Warning
This is a major rewrite (v2.0) and is not backward compatible with v1.x. Please refer to the migration guide for details. For Vite users, ensure you are using version 2.0.3 or later to avoid entry point resolution issues.
- 🎯 Intuitive API — Fluent, chainable methods for all date operations
- 📅 Immutable by Default — All operations return new instances
- 🌍 Timezone Support — Built-in timezone handling with DST awareness
- 🌐 Internationalization — Extensible locale system with human-readable output
- ⏱️ Intervals — Powerful duration/interval handling (like CarbonInterval)
- 📆 Periods — Date range iteration with filtering and transformations
- 📋 Period Collections — Manage and analyze multiple date periods easily
- 📐 Type-Safe — Full TypeScript support with comprehensive types
- 🪶 Zero Dependencies — No external runtime dependencies
npm install chronos-ts
# or
yarn add chronos-ts
# or
pnpm add chronos-tsimport { Chronos, ChronosInterval, ChronosPeriod } from 'chronos-ts';
// Create dates
const now = Chronos.now();
const birthday = Chronos.create(1990, 6, 15);
const parsed = Chronos.parse('2024-03-15T10:30:00');
// Manipulate dates
const nextWeek = now.addWeeks(1);
const lastMonth = now.subtractMonths(1);
const startOfDay = now.startOf('day');
// Format dates
console.log(now.format('YYYY-MM-DD HH:mm:ss')); // "2024-03-15 14:30:45"
console.log(now.diffForHumans(birthday)); // "33 years ago"
// Work with intervals
const interval = ChronosInterval.create({ hours: 2, minutes: 30 });
console.log(interval.forHumans()); // "2 hours 30 minutes"
// Iterate over periods
const thisMonth = ChronosPeriod.thisMonth();
for (const day of thisMonth) {
console.log(day.format('YYYY-MM-DD'));
}For detailed documentation on all classes and methods, please refer to the API Reference.
- Chronos: The main class for date/time manipulation.
- ChronosInterval: Represents a duration of time.
- ChronosPeriod: Represents a date range or schedule.
- ChronosPeriodCollection: Manages collections of periods.
- ChronosTimezone: Timezone utilities.
Chronos-ts includes built-in support for English and Spanish, with an extensible locale system.
import { Chronos, registerLocale, getLocale } from 'chronos-ts';
// Use built-in locale
const date = Chronos.now().locale('es');
date.format('dddd, D [de] MMMM [de] YYYY');
// "viernes, 15 de marzo de 2024"
// Human-readable in Spanish
date.diffForHumans(Chronos.yesterday());
// "hace 1 día"
// Register custom locale
registerLocale({
code: 'de',
months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
monthsShort: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun',
'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch',
'Donnerstag', 'Freitag', 'Samstag'],
weekdaysShort: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
weekdaysMin: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
relativeTime: {
future: 'in %s',
past: 'vor %s',
s: 'wenigen Sekunden',
ss: '%d Sekunden',
m: 'einer Minute',
mm: '%d Minuten',
h: 'einer Stunde',
hh: '%d Stunden',
d: 'einem Tag',
dd: '%d Tagen',
M: 'einem Monat',
MM: '%d Monaten',
y: 'einem Jahr',
yy: '%d Jahren',
},
});import { Chronos } from 'chronos-ts';
// Set global configuration
Chronos.configure({
defaultTimezone: 'America/New_York',
defaultLocale: 'en',
});
// Set test/mock time (useful for testing)
Chronos.setTestNow(Chronos.create(2024, 1, 1));
const now = Chronos.now(); // Returns 2024-01-01
// Reset test time
Chronos.setTestNow(null);import { Chronos, ChronosPeriod, ChronosInterval } from 'chronos-ts';
// Conference dates
const conference = {
start: Chronos.create(2024, 6, 15, 9, 0),
end: Chronos.create(2024, 6, 17, 18, 0),
};
// Check if a session conflicts
const session = Chronos.create(2024, 6, 16, 14, 0);
const isDuringConference = session.isBetween(conference.start, conference.end);
// Create weekly recurring meeting
const meetings = ChronosPeriod
.create(
Chronos.now(),
Chronos.now().addMonths(3),
{ weeks: 1 }
)
.filter(date => date.dayOfWeek === 1) // Mondays only
.toArray();import { Chronos, ChronosInterval } from 'chronos-ts';
class Subscription {
constructor(
public startDate: Chronos,
public interval: ChronosInterval
) {}
get nextBillingDate(): Chronos {
return this.startDate.add(this.interval);
}
isActive(): boolean {
return Chronos.now().isBefore(this.nextBillingDate);
}
daysUntilRenewal(): number {
return this.nextBillingDate.diffInDays(Chronos.now());
}
}
const monthly = new Subscription(
Chronos.now(),
ChronosInterval.months(1)
);
console.log(`Days until renewal: ${monthly.daysUntilRenewal()}`);import { Chronos, ChronosPeriod } from 'chronos-ts';
// Get working days this month
const workingDays = ChronosPeriod
.thisMonth()
.filterWeekdays()
.toArray();
console.log(`Working days this month: ${workingDays.length}`);
// Calculate hours worked
const clockIn = Chronos.create(2024, 3, 15, 9, 0);
const clockOut = Chronos.create(2024, 3, 15, 17, 30);
const hoursWorked = clockOut.diffInHours(clockIn);
const overtime = Math.max(0, hoursWorked - 8);
console.log(`Hours worked: ${hoursWorked}`);
console.log(`Overtime: ${overtime}`);import { Chronos } from 'chronos-ts';
function getAge(birthDate: Chronos): { years: number; months: number; days: number } {
const now = Chronos.now();
return {
years: now.diffInYears(birthDate),
months: now.diffInMonths(birthDate) % 12,
days: now.diffInDays(birthDate.addYears(now.diffInYears(birthDate))) % 30,
};
}
const birthday = Chronos.create(1990, 6, 15);
const age = getAge(birthday);
console.log(`Age: ${age.years} years, ${age.months} months, ${age.days} days`);import { Chronos } from 'chronos-ts';
describe('MyFeature', () => {
beforeEach(() => {
// Freeze time for consistent tests
Chronos.setTestNow(Chronos.create(2024, 1, 15, 12, 0, 0));
});
afterEach(() => {
// Reset to real time
Chronos.setTestNow(null);
});
it('should calculate correct deadline', () => {
const deadline = Chronos.now().addDays(30);
expect(deadline.format('YYYY-MM-DD')).toBe('2024-02-14');
});
});| Feature | Chronos-ts | Day.js | Moment.js | date-fns |
|---|---|---|---|---|
| Immutable | ✅ | ✅ | ❌ | ✅ |
| TypeScript | ✅ Native | Plugin | Plugin | ✅ Native |
| Tree-shakeable | ✅ | ✅ | ❌ | ✅ |
| Intervals | ✅ | Plugin | ✅ | ❌ |
| Periods | ✅ | ❌ | ❌ | ❌ |
| Timezones | ✅ | Plugin | Plugin | ✅ |
| Zero deps | ✅ | ✅ | ❌ | ✅ |
| API Style | Fluent | Fluent | Fluent | Functional |
Contributions, issues, and feature requests are welcome! See CONTRIBUTING.md for guidelines.
# Clone the repository
git clone https://github.com/hendurhance/chronos-ts.git
# Install dependencies
npm install
# Run tests
npm test
# Build
npm run buildThis project is licensed under the MIT License — see the LICENSE file for details.
- Carbon PHP — Primary API inspiration
- Day.js — Immutability patterns
- Moment.js — Format string patterns
- Period - Complex period comparisons
Made with ❤️ by the Chronos-ts team