timezone-date-utils
v1.2.9
Published
Comprehensive date and time utilities using moment-timezone with IST as default timezone. Features strict TypeScript types, type guards, validators, and runtime assertions. Works seamlessly in both Node.js backend and browser frontend environments.
Downloads
1,464
Maintainers
Readme
timezone-date-utils
Comprehensive date and time utilities using moment-timezone with IST (Indian Standard Time) as the default timezone. Built for hotel management systems with specific hotel operations support. Works seamlessly in both Node.js backend and browser frontend environments.
✨ Features
- ✅ Universal/Isomorphic - Works in both Node.js and browsers
- ✅ Timezone-Aware - All operations respect timezones, default IST
- ✅ moment-timezone - Built on battle-tested library
- ✅ Hotel-Specific - Check-in/out times, night audit, etc.
- ✅ Comprehensive - 60+ utility functions
- ✅ Type-Safe - Full TypeScript support with strict types
- ✅ Runtime Validation - Type guards, validators, and assertions
- ✅ Business Logic - Weekend/weekday detection, business days
- ✅ Flexible Formatting - Multiple display formats
- ✅ ESM & CJS - Supports both module systems
- ✅ Branded Types - Enhanced type safety with branded primitives
- ✅ Immutable - Readonly types for data integrity
📦 Installation
npm install timezone-date-utils
# or
yarn add timezone-date-utils
# or
pnpm add timezone-date-utilsPeer Dependencies
npm install moment-timezone📚 Documentation
- Quick Reference - Quick function reference
- Strict Types Guide - Complete guide to strict typing, type guards, and validators
- Development Guide - Development and contribution guide
- Examples - Practical examples
🚀 Usage
Backend (Node.js / NestJS / Express)
import * as DateUtil from 'timezone-date-utils';
// or
import { now, formatDisplay, calculateNights } from 'timezone-date-utils';
// Get current time in IST
const currentTime = DateUtil.now();
// Create a date
const checkIn = DateUtil.createDate('2025-12-15');
// Format for display
const displayDate = DateUtil.formatDisplay(checkIn); // "15 Dec 2025"
// Calculate nights between dates
const checkOut = DateUtil.createDate('2025-12-18');
const nights = DateUtil.calculateNights(checkIn, checkOut); // 3Frontend (React / Next.js / Vue / Angular)
// React example
import { now, formatDisplay, isWeekend } from 'timezone-date-utils';
import { useEffect, useState } from 'react';
function DateDisplay() {
const [currentDate, setCurrentDate] = useState('');
useEffect(() => {
const date = now();
const formatted = formatDisplay(date);
const weekend = isWeekend(date);
setCurrentDate(`${formatted}${weekend ? ' (Weekend)' : ''}`);
}, []);
return <div>{currentDate}</div>;
}// Next.js example
'use client';
import { calculateNights, formatDisplay } from 'timezone-date-utils';
export default function BookingCalculator({ checkIn, checkOut }) {
const nights = calculateNights(checkIn, checkOut);
return (
<div>
<p>Check-in: {formatDisplay(checkIn)}</p>
<p>Check-out: {formatDisplay(checkOut)}</p>
<p>Nights: {nights}</p>
</div>
);
}📖 API Reference
Creation and Parsing
// Current time
DateUtil.now(); // Current time in IST
DateUtil.now('America/New_York'); // Current time in EST
// Create from various inputs
DateUtil.createDate('2025-12-15');
DateUtil.createDate(new Date());
DateUtil.createDate(1702636800000); // timestamp
// Parse with format
DateUtil.parseDate('15-12-2025', 'DD-MM-YYYY');
DateUtil.parseDateStrict('15/12/2025', 'DD/MM/YYYY');
// From timestamp
DateUtil.fromTimestamp(1702636800000);
DateUtil.fromUnix(1702636800); // Unix timestamp (seconds)
// From components
DateUtil.fromComponents(2025, 11, 15, 14, 30, 0); // Dec 15, 2025 2:30 PMFormatting
const date = DateUtil.createDate('2025-12-15');
DateUtil.format(date); // "15 Dec 2025, 02:00 PM"
DateUtil.formatDisplay(date); // "15 Dec 2025"
DateUtil.formatDisplayWithTime(date); // "15 Dec 2025, 02:00 PM"
DateUtil.toISOString(date); // "2025-12-15T14:00:00.000+05:30"
DateUtil.toISODate(date); // "2025-12-15"
DateUtil.toDBFormat(date); // "2025-12-15 14:00:00"
DateUtil.toTimestamp(date); // milliseconds
DateUtil.toUnix(date); // secondsManipulation
const date = DateUtil.createDate('2025-12-15');
// Add/Subtract
DateUtil.add(date, 3, 'days'); // Dec 18
DateUtil.subtract(date, 1, 'month'); // Nov 15
// Duration
DateUtil.addDuration(date, { days: 3, hours: 2 });
DateUtil.subtractDuration(date, { weeks: 1 });
// Start/End of period
DateUtil.startOf(date, 'month'); // Dec 1, 2025 00:00:00
DateUtil.endOf(date, 'month'); // Dec 31, 2025 23:59:59
// Set values
DateUtil.setTime(date, 14, 30, 0); // Set to 2:30 PM
DateUtil.set(date, { year: 2026, month: 0 }); // Jan 2026Comparison
const date1 = DateUtil.createDate('2025-12-15');
const date2 = DateUtil.createDate('2025-12-20');
DateUtil.isBefore(date1, date2); // true
DateUtil.isAfter(date1, date2); // false
DateUtil.isSame(date1, date1); // true
DateUtil.isSameOrBefore(date1, date2); // true
DateUtil.isSameOrAfter(date1, date2); // false
DateUtil.isBetween(
'2025-12-17',
'2025-12-15',
'2025-12-20'
); // trueDifference Calculations
const date1 = DateUtil.createDate('2025-12-15');
const date2 = DateUtil.createDate('2025-12-20');
DateUtil.diff(date1, date2, 'days'); // -5
DateUtil.diffInDays(date1, date2); // -5
DateUtil.diffInHours(date1, date2); // -120
DateUtil.diffInMinutes(date1, date2); // -7200Validation & Queries
const date = DateUtil.createDate('2025-12-15');
DateUtil.isValid(date); // true
DateUtil.isLeapYear(date); // false
DateUtil.isToday(date); // depends on current date
DateUtil.isYesterday(date);
DateUtil.isTomorrow(date);
DateUtil.isPast(date);
DateUtil.isFuture(date);
DateUtil.isWeekend(date);
DateUtil.isWeekday(date);
// Validation helpers
DateUtil.isValidYYYYMMDD('2025-12-15'); // true
DateUtil.isValidDDMMYYYY('15-12-2025'); // true
DateUtil.isValidDDMMYYYYSlash('15/12/2025'); // true
DateUtil.isSameDay(date1, date2); // Compare dates ignoring timeAge Calculation
// Calculate age from date of birth
const age = DateUtil.calculateAge('1990-05-15'); // Current age
// Calculate age from DD/MM/YYYY format
const ageFromIndian = DateUtil.calculateAgeFromDDMMYYYY('15/05/1990'); // 34
// Get detailed age
const detailedAge = DateUtil.getDetailedAge('1990-05-15');
// { years: 34, months: 7, days: 1 }Date/Time Separation
const dateTime = DateUtil.createDate('2025-12-15 14:30:00');
// Separate into date and time
const { date, time } = DateUtil.separateDateTime(dateTime);
// date: "15-12-2025", time: "14:30"
// With AM/PM format
const separated = DateUtil.separateDateTimeWithAMPM(dateTime);
// { date: "15-12-2025", time: "02:30 PM" }Indian/Specialized Formatting
const date = DateUtil.createDate('2025-12-15 14:30:00');
// Indian formats
DateUtil.formatIndianDate(date); // "15-12-2025"
DateUtil.formatIndianDateSlash(date); // "15/12/2025"
DateUtil.formatIndianDateTime(date); // "15/12/2025, 14:30"
// Invoice and report formats
DateUtil.formatInvoiceDate(date); // "15-12-2025, 2:30 PM"
DateUtil.formatDatabaseDateTime(date); // "2025-12-15 14:30:00"
DateUtil.formatRoomSalesDate(date); // "2025-12-15 14:30"
// Time only
DateUtil.formatTimeOnly(date); // "14:30"
DateUtil.formatTime12Hour(date); // "02:30 PM"
DateUtil.formatFullMonthDate(date); // "15 Dec 2025"Date Range Operations
// Generate date arrays
const dates = DateUtil.getDateArray('2025-12-15', '2025-12-20');
// Array of Date objects
// Range in chunks (for large ranges)
const chunks = DateUtil.dateRangeInChunks('2025-01-01', '2025-12-31', 30);
// Array of arrays, each with max 30 dates
// Overlap detection
const overlap = DateUtil.getOverlapDays(
'2025-12-15', '2025-12-20',
'2025-12-18', '2025-12-25'
); // 2 days overlap
const hasOverlap = DateUtil.doRangesOverlap(
'2025-12-15', '2025-12-20',
'2025-12-18', '2025-12-25'
); // true
// Check if date is in overlap period
DateUtil.isInOverlapPeriod(
'2025-12-17',
'2025-12-15',
'2025-12-20'
); // trueAdvanced Operations
// Time adjustments
DateUtil.adjustTimeByOffset(date, 5, 30); // Add 5 hours 30 minutes
// Convenient shortcuts
DateUtil.daysAgo(7); // Date 7 days ago
DateUtil.daysFromNow(14); // Date 14 days from now
DateUtil.hoursAgo(24); // Date 24 hours ago
DateUtil.hoursFromNow(12); // Date 12 hours from now
// Sorting
DateUtil.sortDatesAscending([date3, date1, date2]);
DateUtil.sortDatesDescending([date1, date2, date3]);
DateUtil.getEarliestDate([date1, date2, date3]);
DateUtil.getLatestDate([date1, date2, date3]);
// Conversions
DateUtil.dateToMoment(new Date());
DateUtil.momentToDate(momentInstance);
DateUtil.isoToMoment('2025-12-15T14:30:00Z');
// Parse multiple formats
DateUtil.parseMultipleFormats(
'15/12/2025',
['DD/MM/YYYY', 'DD-MM-YYYY', 'YYYY-MM-DD']
);Date Keys for Grouping
// Generate keys for data grouping
DateUtil.toDateKey(date); // "2025-12-15"
DateUtil.toMonthKey(date); // "2025-12"
DateUtil.toYearKey(date); // "2025"
DateUtil.toWeekKey(date); // "2025-W50"Getters
const date = DateUtil.createDate('2025-12-15 14:30:45');
DateUtil.getYear(date); // 2025
DateUtil.getMonth(date); // 11 (0-indexed)
DateUtil.getDate(date); // 15
DateUtil.getDayOfWeek(date); // 1 (Monday)
DateUtil.getDayOfYear(date); // 349
DateUtil.getHour(date); // 14
DateUtil.getMinute(date); // 30
DateUtil.getSecond(date); // 45Hotel-Specific Functions
const checkIn = DateUtil.createDate('2025-12-15');
const checkOut = DateUtil.createDate('2025-12-18');
// Calculate nights
DateUtil.calculateNights(checkIn, checkOut); // 3
// Check-in/out times
DateUtil.getCheckInTime(checkIn); // 2:00 PM on Dec 15
DateUtil.getCheckOutTime(checkOut); // 11:00 AM on Dec 18
// Check timing
DateUtil.isPastCheckIn(); // true if after 2 PM
DateUtil.isPastCheckOut(); // true if after 11 AM
// Night audit
DateUtil.getNightAuditDate(); // Current audit dateBusiness Days
DateUtil.getNextBusinessDay(); // Next weekday
DateUtil.getPreviousBusinessDay(); // Previous weekday
DateUtil.countBusinessDays(
'2025-12-15',
'2025-12-20'
); // Count weekdays onlyDate Ranges
// Create range
const range = DateUtil.createDateRange('2025-12-15', '2025-12-20');
// Get all dates in range
DateUtil.dateRange('2025-12-15', '2025-12-20'); // Array of Moments
// Predefined ranges
DateUtil.getTodayRange();
DateUtil.getThisWeekRange();
DateUtil.getThisMonthRange();
DateUtil.getThisYearRange();
DateUtil.getLastNDaysRange(7); // Last 7 daysUtility Functions
// Min/Max
DateUtil.min([date1, date2, date3]);
DateUtil.max([date1, date2, date3]);
// Clone
DateUtil.clone(date);
// Timezone conversion
DateUtil.toTimezone(date, 'America/New_York');
// Relative time
DateUtil.fromNow(date); // "2 days ago"
DateUtil.toNow(date); // "in 2 days"
DateUtil.calendar(date); // "Today at 2:30 PM"
// Duration
DateUtil.getDuration(date1, date2); // "5 days"
DateUtil.formatDuration(300000); // "5m"🌍 Timezones
import { TIMEZONES } from 'timezone-date-utils';
// Available timezones
TIMEZONES.IST // 'Asia/Kolkata' (default)
TIMEZONES.UTC // 'UTC'
TIMEZONES.EST // 'America/New_York'
TIMEZONES.PST // 'America/Los_Angeles'
TIMEZONES.GMT // 'Europe/London'
TIMEZONES.DUBAI // 'Asia/Dubai'
TIMEZONES.SINGAPORE // 'Asia/Singapore'
// ... and more📅 Constants
import {
DATE_FORMATS,
DAY_OF_WEEK,
MONTH_OF_YEAR,
HOTEL_TIMINGS,
BUSINESS_DAYS,
WEEKEND_DAYS,
MILLISECONDS_IN,
} from 'timezone-date-utils';
// Date formats
DATE_FORMATS.ISO_DATE // 'YYYY-MM-DD'
DATE_FORMATS.DISPLAY_DATE // 'DD MMM YYYY'
DATE_FORMATS.DISPLAY_DATETIME // 'DD MMM YYYY, hh:mm A'
// Days and months
DAY_OF_WEEK.MONDAY // 1
MONTH_OF_YEAR.DECEMBER // 11
// Hotel timings
HOTEL_TIMINGS.CHECK_IN_TIME // '14:00'
HOTEL_TIMINGS.CHECK_OUT_TIME // '11:00'
// Time constants
MILLISECONDS_IN.DAY // 86400000🔧 TypeScript Support
Full TypeScript support with comprehensive strict types, type guards, validators, and assertions.
Basic Types
import type {
DateInput,
DateFormat,
Timezone,
DateRange,
Duration,
BookingDates,
CalendarDay,
Moment,
} from 'timezone-date-utils';Strict Types & Branded Types
import type {
// Branded types for enhanced type safety
ISODateString,
ISODateTimeString,
UnixTimestamp,
TimeFormat,
PositiveInteger,
NonNegativeInteger,
// Strict numeric types
DayOfWeek, // 0-6
MonthOfYear, // 0-11
HourOfDay, // 0-23
// Strict complex types
StrictBusinessHours,
StrictRecurringPattern,
StrictDuration,
} from 'timezone-date-utils';Type Guards & Validators
import {
// Type guards
isISODateString,
isPositiveInteger,
isDayOfWeek,
isTimeFormat,
// Validators (return branded types or null)
toISODateString,
toPositiveInteger,
validateDateString,
// Assertions (throw on invalid)
assertPositiveInteger,
assertDayOfWeek,
// Grouped utilities
TypeGuards,
Validators,
Assertions,
} from 'timezone-date-utils';
// Example usage
const dateStr = '2024-01-15';
if (isISODateString(dateStr)) {
// dateStr is now type ISODateString
console.log('Valid ISO date:', dateStr);
}
// With validator
const validDate = toISODateString('2024-01-15'); // ISODateString | null
// With assertion
assertPositiveInteger(nights, 'nights'); // Throws if invalidComplete Type-Safe Example
import {
ISODateString,
PositiveInteger,
BookingStatus,
toISODateString,
toPositiveInteger,
calculateNights,
} from 'timezone-date-utils';
interface Booking {
readonly id: string;
readonly checkIn: ISODateString;
readonly checkOut: ISODateString;
readonly nights: PositiveInteger;
readonly status: BookingStatus;
}
function createBooking(checkIn: string, checkOut: string): Booking | null {
const validCheckIn = toISODateString(checkIn);
const validCheckOut = toISODateString(checkOut);
if (!validCheckIn || !validCheckOut) return null;
const nights = toPositiveInteger(calculateNights(validCheckIn, validCheckOut));
if (!nights) return null;
return {
id: crypto.randomUUID(),
checkIn: validCheckIn,
checkOut: validCheckOut,
nights,
status: 'confirmed',
};
}📖 See Strict Types Guide for comprehensive documentation on strict types, type guards, validators, and best practices.
🎯 Common Use Cases
Booking System
import { calculateNights, formatDisplay, isWeekend } from 'timezone-date-utils';
function calculateBooking(checkIn: string, checkOut: string) {
const nights = calculateNights(checkIn, checkOut);
const hasWeekendStay = // ... custom logic using isWeekend
return {
checkIn: formatDisplay(checkIn),
checkOut: formatDisplay(checkOut),
nights,
hasWeekendStay,
};
}Availability Calendar
import { dateRange, isWeekend, isPast } from 'timezone-date-utils';
function getCalendarDays(startDate: string, endDate: string) {
const dates = dateRange(startDate, endDate);
return dates.map(date => ({
date: date.format('YYYY-MM-DD'),
isWeekend: isWeekend(date),
isPast: isPast(date),
isAvailable: true, // Add your logic
}));
}Report Generation
import { getThisMonthRange, formatDisplay } from 'timezone-date-utils';
function generateMonthlyReport() {
const { start, end } = getThisMonthRange();
return {
period: `${formatDisplay(start)} - ${formatDisplay(end)}`,
// ... fetch and process data
};
}📄 License
MIT
👥 Author
DigiStay
🐛 Issues
Report issues at: https://github.com/digistayai/date-utils/issues
🤝 Contributing
Contributions welcome! Please read our contributing guidelines.
Made with ❤️ for the hospitality industry
