@seawingai/wingdate
v1.0.1
Published
Recurring schedule, ISO, UTC handling with ease
Maintainers
Readme
WingDate
A powerful TypeScript/JavaScript library for handling recurring schedules, ISO dates, and UTC timezone conversions with ease. Built on top of Luxon and RRule for robust date manipulation and recurrence rules.
Features
- 🕐 Timezone-aware date handling with automatic user timezone detection
- 🔄 Recurring schedules with RRule integration
- 📅 ISO 8601 compliance for reliable date parsing and formatting
- ⚡ Lightweight and fast with minimal dependencies
- 🎯 TypeScript support with full type definitions
- 🧪 Comprehensive testing with Jest
Installation
npm install @seawingai/wingdate
# or
pnpm add @seawingai/wingdate
# or
yarn add @seawingai/wingdateQuick Start
import { WingDate, Recurrence } from '@seawingai/wingdate';
// Create a date instance
const date = new WingDate('2024-01-15T10:30:00Z');
// Get current date
const now = WingDate.now();
// Convert to UTC
const utc = WingDate.toUTC('2024-01-15T10:30:00-05:00');
// Format dates
const formatted = WingDate.format('2024-01-15T10:30:00Z', 'America/New_York', 'MMM dd, yyyy');
// Output: "Jan 15, 2024"Core Usage
Creating Dates
import { WingDate } from '@seawingai/wingdate';
// From ISO string
const date1 = new WingDate('2024-01-15T10:30:00Z');
// From JavaScript Date
const date2 = WingDate.fromJSDate(new Date());
// Current date
const now = WingDate.now();
// With custom timezone
const date3 = new WingDate('2024-01-15T10:30:00Z', 'America/New_York');Date Comparisons
const date = new WingDate('2024-01-15T10:30:00Z');
// Equality
date.eq('2024-01-15T10:30:00Z'); // true
date.neq('2024-01-16T10:30:00Z'); // true
// Greater/Less than
date.gt('2024-01-14T10:30:00Z'); // true
date.lt('2024-01-16T10:30:00Z'); // true
date.gte('2024-01-15T10:30:00Z'); // true
date.lte('2024-01-15T10:30:00Z'); // trueTimezone Conversions
// Convert to UTC
const utc = WingDate.toUTC('2024-01-15T10:30:00-05:00');
// Output: "2024-01-15T15:30:00.000Z"
// Convert from UTC to local timezone
const local = WingDate.toISO('2024-01-15T15:30:00Z', 'America/New_York');
// Output: "2024-01-15T10:30:00.000-05:00"
// Format with custom timezone
const formatted = WingDate.format('2024-01-15T15:30:00Z', 'America/New_York', 'yyyy-MM-dd HH:mm ZZZZ');
// Output: "2024-01-15 10:30 EST"Recurring Schedules
Basic Recurrence
import { Recurrence } from '@seawingai/wingdate';
// Daily recurrence
const daily = new Recurrence({
frequency: 'daily',
interval: 1
});
// Weekly recurrence (every Monday and Wednesday)
const weekly = new Recurrence({
frequency: 'weekly',
interval: 1,
byDay: ['MO', 'WE']
});
// Monthly recurrence (every 2 months)
const monthly = new Recurrence({
frequency: 'monthly',
interval: 2
});Working with Recurrences
const startDate = new WingDate('2024-01-15T10:30:00Z');
// Daily recurrence
const daily = new Recurrence({ frequency: 'daily' });
// Get all occurrences
const allDates = startDate.all(daily);
// Get occurrences within a month
const monthlyDates = startDate.within(daily, 'month');
// Get occurrences between two dates
const betweenDates = startDate.between(daily, '2024-02-15T10:30:00Z');
// Check if a date is due
const isDue = startDate.due(daily, '2024-01-16T10:30:00Z');Advanced Recurrence Examples
// Weekly meeting (every Monday at 9 AM)
const weeklyMeeting = new Recurrence({
frequency: 'weekly',
interval: 1,
byDay: ['MO']
});
// Bi-weekly event (every 2 weeks)
const biWeekly = new Recurrence({
frequency: 'weekly',
interval: 2
});
// Monthly event with end date
const monthlyEvent = new Recurrence({
frequency: 'monthly',
interval: 1,
until: '2024-12-31T23:59:59Z'
});
// Limited occurrences (only 10 times)
const limitedEvent = new Recurrence({
frequency: 'daily',
interval: 1,
count: 10
});Utility Methods
Date Formatting
// Custom format
const formatted = WingDate.format(
'2024-01-15T15:30:00Z',
'America/New_York',
'EEEE, MMMM dd, yyyy "at" h:mm a'
);
// Output: "Monday, January 15, 2024 at 10:30 AM"
// Different timezones
const tokyo = WingDate.format('2024-01-15T15:30:00Z', 'Asia/Tokyo', 'yyyy-MM-dd HH:mm');
// Output: "2024-01-16 00:30"Time Comparisons
const date1 = new WingDate('2024-01-15T10:30:00Z');
const date2 = new WingDate('2024-01-16T10:30:00Z');
// Check if same time (ignoring date)
date1.sameTime(date2); // true
// Check if overdue
date1.overdue('2024-01-14T10:30:00Z'); // trueAPI Reference
WingDate Class
Constructor
new WingDate(dateISO: string, userTimeZone?: string)Static Methods
WingDate.now(userTimeZone?: string): WingDateWingDate.toUTC(dateISO: string, userTimeZone?: string): stringWingDate.toISO(utcISO: string, userTimeZone?: string): stringWingDate.format(utcISO: string, userTimeZone?: string, format?: string): stringWingDate.fromJSDate(date: Date, userTimeZone?: string): WingDate
Instance Methods
eq(dateISO: string, userTimeZone?: string): booleanneq(dateISO: string, userTimeZone?: string): booleangt(dateISO: string, userTimeZone?: string): booleangte(dateISO: string, userTimeZone?: string): booleanlt(dateISO: string, userTimeZone?: string): booleanlte(dateISO: string, userTimeZone?: string): booleanall(recurrence: Recurrence): WingDate[]within(recurrence: Recurrence, unit?: DateTimeUnit, includeDates?: boolean): WingDate[]between(recurrence: Recurrence, endDate: string, includeDates?: boolean): WingDate[]due(recurrence: Recurrence, date: string | WingDate, userTimeZone?: string): boolean
Recurrence Class
Constructor
new Recurrence(recurrence: IRecurrence)Interface
interface IRecurrence {
frequency: 'daily' | 'weekly' | 'monthly' | 'yearly' | 'hourly' | 'minutely' | 'secondly';
interval?: number;
byDay?: string[]; // ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']
count?: number;
until?: string;
}Examples
Calendar Application
import { WingDate, Recurrence } from '@seawingai/wingdate';
// Create recurring events
const teamMeeting = new Recurrence({
frequency: 'weekly',
interval: 1,
byDay: ['MO', 'WE', 'FR']
});
const startDate = new WingDate('2024-01-15T09:00:00Z');
// Get all meetings for the month
const meetings = startDate.within(teamMeeting, 'month');
// Check if today has a meeting
const today = WingDate.now();
const hasMeetingToday = startDate.due(teamMeeting, today);Task Scheduler
// Daily task
const dailyTask = new Recurrence({ frequency: 'daily' });
// Check if task is overdue
const taskDate = new WingDate('2024-01-15T17:00:00Z');
const now = WingDate.now();
if (taskDate.overdue(now)) {
console.log('Task is overdue!');
}Contributing
We welcome contributions! Please see our Contributing Guide for details.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Support
Made with ❤️ by SeaWingAI
