{"id":15292009,"url":"https://github.com/hendurhance/chronos-ts","last_synced_at":"2025-08-13T19:15:19.011Z","repository":{"id":257651343,"uuid":"858975048","full_name":"hendurhance/chronos-ts","owner":"hendurhance","description":"⏰ Flexible period and interval handling library for JavaScript and TypeScript, with support for precise time comparisons and custom intervals.","archived":false,"fork":false,"pushed_at":"2025-06-24T16:19:28.000Z","size":170,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-10T03:32:44.813Z","etag":null,"topics":["calendar","date","date-fns","date-utils","datetime","duration","interval","javascript","npm","range","scheduling","time","time-utils","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/chronos-ts","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hendurhance.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-17T21:20:47.000Z","updated_at":"2025-06-24T16:19:32.000Z","dependencies_parsed_at":"2024-09-17T23:45:35.506Z","dependency_job_id":"546d95d3-cd60-46f6-9d3c-1623fff1971e","html_url":"https://github.com/hendurhance/chronos-ts","commit_stats":null,"previous_names":["hendurhance/chronos-ts"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/hendurhance/chronos-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendurhance%2Fchronos-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendurhance%2Fchronos-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendurhance%2Fchronos-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendurhance%2Fchronos-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hendurhance","download_url":"https://codeload.github.com/hendurhance/chronos-ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendurhance%2Fchronos-ts/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270296564,"owners_count":24560364,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","date","date-fns","date-utils","datetime","duration","interval","javascript","npm","range","scheduling","time","time-utils","typescript"],"created_at":"2024-09-30T16:16:10.100Z","updated_at":"2025-08-13T19:15:18.983Z","avatar_url":"https://github.com/hendurhance.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chronos-ts ⏰\nChronos-ts from the name is inspired by the Greek god of time, Chronos. It is a comprehensive TypeScript package for handling time periods, intervals, and date-related operations.\n\n## Table of Contents\n- [Chronos-ts ⏰](#chronos-ts-)\n  - [Table of Contents](#table-of-contents)\n  - [Installation](#installation)\n  - [Overview](#overview)\n  - [Usage](#usage)\n    - [Creating and Manipulating Periods](#creating-and-manipulating-periods)\n    - [Working with Intervals](#working-with-intervals)\n    - [Using Utility Functions](#using-utility-functions)\n  - [API Reference](#api-reference)\n    - [Classes](#classes)\n      - [Period](#period)\n        - [Constructor](#constructor)\n        - [Methods](#methods)\n        - [Fluent API Methods](#fluent-api-methods)\n      - [Interval](#interval)\n        - [Methods](#methods-1)\n      - [Enums](#enums)\n        - [Precision](#precision)\n    - [Utility Function](#utility-function)\n    - [Real-world Scenarios](#real-world-scenarios)\n      - [**1. Event Planning and Management**](#1-event-planning-and-management)\n      - [**2. Financial  Reporting Periods**](#2-financial--reporting-periods)\n      - [**3. Employee Leave Management**](#3-employee-leave-management)\n      - [**4.  Project Timeline Management**](#4--project-timeline-management)\n      - [**5. Subscription Billing Cycle Management**](#5-subscription-billing-cycle-management)\n      - [**6. Employee Shift Management**](#6-employee-shift-management)\n      - [**7. Travel Itinerary Planning**](#7-travel-itinerary-planning)\n  - [Contributing 🤝](#contributing-)\n  - [License 📝](#license-)\n  - [Acknowledgements 🙏](#acknowledgements-)\n\n## Installation\n```bash\nnpm install chronos-ts\n\n# or\nyarn add chronos-ts\n\n# or\n\npnpm add chronos-ts\n```\n\n## Overview\nThis package provides an easy-to-use API for working with periods and intervals, along with precise handling of date and time logic. Inspired by the [spatie/period](https://github.com/spatie/period) package in PHP, this package provides support for both TypeScript and JavaScript environments, offering advanced time manipulation. It offers a user-friendly API for working with periods and intervals, providing precise date and time logic handling. Key features include:\n- Flexible period creation and manipulation with customizable precision (minute to year)\n- Interval generation for recurring events (e.g., \"every 3 days\")\n- Comprehensive period comparisons (overlaps, contains, adjacent)\n- Precise start/end date handling with various time units\n- Advanced operations like symmetric differences and unions between periods\n- Adjacent period detection for seamless time range management\n- Extensive utility functions for common date operations and formatting\n\nWhether you're building scheduling systems, financial applications, or any project requiring sophisticated time calculations, Chronos simplifies complex time-based operations in both TypeScript and JavaScript environments.\n\n\n## Usage\n### Creating and Manipulating Periods\n```typescript\nimport { Period, Precision, Interval } from 'chronos-ts';\n\n// Create a period for the year 2023\nconst year2023 = new Period('2023-01-01', '2023-12-31', Precision.DAY);\n\n// Check if a date is within the period\nconst isInPeriod = year2023.contains('2023-06-15'); // true\n\n// Create a period for Q2 2023\nconst q2_2023 = new Period('2023-04-01', '2023-06-30', Precision.DAY);\n\n// Check if periods overlap\nconst periodsOverlap = year2023.overlapsWith(q2_2023); // true\n\n// Get the overlapping period\nconst overlap = year2023.overlap(q2_2023);\nconsole.log(overlap?.getStartDate(), overlap?.getEndDate()); // 2023-04-01, 2023-06-30\n\n// Subtract a period\nconst remainingPeriods = year2023.subtract(q2_2023);\nconsole.log(remainingPeriods.length); // 2\nconsole.log(remainingPeriods[0].getStartDate(), remainingPeriods[0].getEndDate()); // 2023-01-01, 2023-04-01\nconsole.log(remainingPeriods[1].getStartDate(), remainingPeriods[1].getEndDate()); // 2023-06-30, 2023-12-31\n\n// Create a period with an interval\nconst weeklyPeriod = new Period('2023-01-01', '2023-12-31', Precision.WEEK, Interval.weeks(1));\n\n// Get dates in the interval\nconst weeklyDates = weeklyPeriod.getDatesInInterval();\nconsole.log(weeklyDates?.length); // 53 (number of weeks in 2023)\n\n// Renew a period - FIXED: Use getter methods\nconst nextYear = year2023.renew();\nconsole.log(nextYear.getStartDate(), nextYear.getEndDate()); // 2024-01-01, 2024-12-31\n\n// Use fluent API\nconst customPeriod = new Period('2023-01-01', '2023-12-31')\n  .setPrecision(Precision.MONTH)\n  .setInterval(Interval.months(3));\n\nconsole.log(customPeriod.getDatesInInterval()?.length); // 5 (Jan, Apr, Jul, Oct, Jan)\n```\n\n### Working with Intervals\n``` typescript\nimport { Interval } from 'chronos-ts';\n\nconst twoHours = Interval.hours(2);\nconsole.log(twoHours.getMinutesInterval()); // 120\n\nconst threeWeeks = Interval.weeks(3);\nconsole.log(threeWeeks.getMinutesInterval()); // 30240 (3 * 7 * 24 * 60)\n\nconst customInterval = new Interval(30, 2, 1, 0, 1); // 30 minutes, 2 hours, 1 day, 0 weeks, 1 month\nconsole.log(customInterval.getMinutesInterval()); // 44310 (30 + 120 + 1440 + 43200)\n```\n### Using Utility Functions\n```typescript\nimport { addToDate, subtractFromDate, formatDate, parseDate, getWeekNumber, isLeapYear, Precision } from 'chronos-ts';\n\nconst today = new Date();\n\n// Add 3 months to today\nconst futureDate = addToDate(today, 3, Precision.MONTH);\n\n// Subtract 2 weeks from today\nconst pastDate = subtractFromDate(today, 2, Precision.WEEK);\n\n// Format a date\nconst formattedDate = formatDate(today, 'YYYY-MM-DD HH:mm:ss');\n\n// Parse a date string\nconst parsedDate = parseDate('2023-06-15 14:30:00', 'YYYY-MM-DD HH:mm:ss');\n\n// Get the week number\nconst weekNumber = getWeekNumber(today);\n\n// Check if it's a leap year\nconst isLeap = isLeapYear(2024); // true\n```\n\n\n\n## API Reference\n### Classes\n#### Period\nThe `Period` class represents a time period with a start date, end date, precision, and optional interval.\n\n##### Constructor\n```typescript\nconstructor(start: string | Date, end: string | Date, precision: Precision = Precision.DAY, interval: Interval | null = null)\n```\n\n##### Methods\n- `contains(date: string | Date): boolean`: Checks if the given date is within the period.\n- `overlapsWith(other: Period): boolean`: Checks if this period overlaps with another period.\n- `isAdjacentTo(other: Period): boolean`: Checks if this period is adjacent to another period.\n- `getDatesInInterval(): Date[] | null`: Returns an array of dates within the period based on the interval.\n- `getMinutesInInterval(): number`: Returns the number of minutes in the period.\n- `getHoursInInterval(): number`: Returns the number of hours in the period.\n- `getDaysInInterval(): number`: Returns the number of days in the period.\n- `getWeeksInInterval(): number`: Returns the number of weeks in the period.\n- `getMonthsInInterval(): number`: Returns the number of months in the period.\n- `getYearsInInterval(): number`: Returns the number of years in the period.\n- `length(): number`: Returns the length of the period in the specified precision.\n- `overlap(other: Period): Period | null`: Returns the overlapping period with another period, if any.\n- `subtract(other: Period): Period[]`: Subtracts another period from this period.\n- `gap(other: Period): Period | null`: Returns the gap between this period and another period, if any.\n- `symmetricDifference(other: Period): Period[]`: Returns the symmetric difference between this period and another period.\n- `renew(): Period`: Creates a new period of the same length immediately following this period.\n- `union(other: Period): Period[]`: Returns the union of this period with another period.\n\n##### Fluent API Methods\n\n`setStart(start: string | Date): this`: Sets the start date of the period.\n`setEnd(end: string | Date): this`: Sets the end date of the period.\n`setPrecision(precision: Precision): this`: Sets the precision of the period.\n`setInterval(interval: Interval): this`: Sets the interval of the period.\n\n#### Interval\nThe `Interval` class represents a time interval with minutes, hours, days, weeks, and months.\nStatic Methods\n\n- `minutes(minutes: number): Interval:` Creates an interval with the specified number of minutes.\n- `hours(hours: number): Interval`: Creates an interval with the specified number of hours.\n- `days(days: number): Interval`: Creates an interval with the specified number of days.\n- `weeks(weeks: number): Interval`: Creates an interval with the specified number of weeks.\n- `months(months: number): Interval`: Creates an interval with the specified number of months.\n\n##### Methods\n\n`getMinutesInterval(): number`: Returns the total number of minutes in the interval.\n\n\n#### Enums\n##### Precision\nThe Precision enum represents different levels of time precision.\n```typescript\nenum Precision {\n    MINUTE = 'minute',\n    HOUR = 'hour',\n    DAY = 'day',\n    WEEK = 'week',\n    MONTH = 'month',\n    YEAR = 'year',\n}\n```\n### Utility Function\nThe package includes various utility functions for working with dates:\n\n- `getDatesWithInterval(start: Date, end: Date, interval: Interval): Date[]` - Returns an array of dates within the specified interval.\n- `getWeeksWithInterval(start: Date, end: Date, interval: Interval): Date[]` - Returns an array of weeks within the specified interval.\n- `getDaysWithInterval(start: Date, end: Date, interval: Interval): Date[]` - Returns an array of days within the specified interval.\n- `getHoursWithInterval(start: Date, end: Date, interval: Interval): Date[]` - Returns an array of hours within the specified interval.\n- `getMinutesWithInterval(start: Date, end: Date, interval: Interval): Date[]` - Returns an array of minutes within the specified interval.\n- `getMonthsWithInterval(start: Date, end: Date, interval: Interval): Date[]` - Returns an array of months within the specified interval.\n- `getYearsWithInterval(start: Date, end: Date, interval: Interval): Date[]` - Returns an array of years within the specified interval.\n- `addToDate(date: Date, amount: number, unit: Precision): Date` - Adds the specified amount of time to a date.\n- `subtractFromDate(date: Date, amount: number, unit: Precision): Date` - Subtracts the specified amount of time from a date.\n- `isSameDay(date1: Date, date2: Date): boolean` - Checks if two dates are on the same day.\n- `getWeekNumber(date: Date): number` - Returns the week number of a date.\n- `getQuarter(date: Date): number` - Returns the quarter of a date.\n- `isLeapYear(year: number): boolean` - Checks if a year is a leap year.\n- `getDaysInMonth(year: number, month: number): number` - Returns the number of days in a month.\n- `formatDate(date: Date, format: string): string`\n- `parseDate(dateString: string, format: string): Date` - Parses a date string using the specified format.\n- `range(start: number, end: number, step: number = 1): number[]` - Returns an array of numbers within the specified range.\n\n### Real-world Scenarios\n#### **1. Event Planning and Management**\nThe `Period` class can be used to represent events, while the `Interval` class can help manage recurring events.\n``` typescript\nimport { Period, Interval, Precision } from 'chronos-ts';\n\n// Create an event\nconst conference = new Period('2023-09-15 09:00', '2023-09-17 18:00', Precision.HOUR);\n\n// Check if a specific time is during the conference\nconst isDuringConference = conference.contains('2023-09-16 14:30'); // true\n\n// Create a recurring weekly meeting\nconst weeklyMeeting = new Period('2023-01-01 10:00', '2023-12-31 11:00', Precision.HOUR, Interval.weeks(1));\n\n// Get all meeting dates\nconst meetingDates = weeklyMeeting.getDatesInInterval();\n\n// Check for conflicts with the conference\nconst conflictingMeetings = meetingDates?.filter(date =\u003e conference.contains(date)) || [];\nconsole.log(`There are ${conflictingMeetings.length} conflicting meetings during the conference.`);\n```\n\n#### **2. Financial  Reporting Periods**\nUse the `Period` class to represent financial quarters and calculate year-to-date periods.\n``` typescript\nimport { Period, Precision } from 'chronos-ts';\n\nconst q1_2023 = new Period('2023-01-01', '2023-03-31', Precision.DAY);\nconst q2_2023 = new Period('2023-04-01', '2023-06-30', Precision.DAY);\nconst q3_2023 = new Period('2023-07-01', '2023-09-30', Precision.DAY);\nconst q4_2023 = new Period('2023-10-01', '2023-12-31', Precision.DAY);\n\n// Calculate Year-to-Date period - FIXED: Use getter method\nconst ytd = (currentQuarter: Period): Period =\u003e {\n  return new Period('2023-01-01', currentQuarter.getEndDate(), Precision.DAY);\n};\n\nconst q3YTD = ytd(q3_2023);\nconsole.log(`Q3 YTD period: ${q3YTD.getStartDate().toDateString()} - ${q3YTD.getEndDate().toDateString()}`);\n\n// Calculate quarter-over-quarter growth\nconst calculateQoQGrowth = (currentQuarter: number, previousQuarter: number): string =\u003e {\n  const growth = (currentQuarter - previousQuarter) / previousQuarter * 100;\n  return `${growth.toFixed(2)}%`;\n};\n\nconst q2Revenue = 1000000;\nconst q3Revenue = 1200000;\nconsole.log(`Q3 QoQ Growth: ${calculateQoQGrowth(q3Revenue, q2Revenue)}`);\n```\n\n#### **3. Employee Leave Management**\nUse the `Period` class to manage employee leave requests and calculate leave balances.\n``` typescript\nimport { Period, Precision } from 'chronos-ts';\n\n// Create a leave request period\nconst leaveRequest = new Period('2023-09-15', '2023-09-17', Precision.DAY);\n\n// Check if the leave request overlaps with existing leave periods\nconst existingLeaves = [\n  new Period('2023-09-10', '2023-09-14', Precision.DAY),\n  new Period('2023-09-18', '2023-09-20', Precision.DAY),\n];\n\nconst overlappingLeaves = existingLeaves.filter(leave =\u003e leaveRequest.overlapsWith(leave));\nconsole.log(`There are ${overlappingLeaves.length} overlapping leave requests.`);\n\n// Calculate remaining leave balance\nconst totalLeaveDays = 20;\nconst usedLeaveDays = existingLeaves.reduce((total, leave) =\u003e total + leave.length(), 0);\nconst remainingLeaveDays = totalLeaveDays - usedLeaveDays;\nconsole.log(`Remaining leave days: ${remainingLeaveDays}`);\n\n// Renew leave balance for the next year\nconst nextYearLeaveBalance = remainingLeaveDays \u003e 0 ? new Period('2024-01-01', '2024-12-31') : null;\nconsole.log(`Next year's leave balance: ${nextYearLeaveBalance ? nextYearLeaveBalance.length() : 0} days`);\n\n```\n\n#### **4.  Project Timeline Management**\nUse the Period class to manage project timelines and track overlapping tasks.\n``` typescript\nimport { Period, Precision } from 'chronos-ts';\n\nconst projectTimeline = new Period('2023-01-01', '2023-12-31', Precision.DAY);\n\nconst tasks = [\n  new Period('2023-01-15', '2023-03-31', Precision.DAY),\n  new Period('2023-03-01', '2023-05-15', Precision.DAY),\n  new Period('2023-05-01', '2023-08-31', Precision.DAY),\n  new Period('2023-08-15', '2023-11-30', Precision.DAY),\n];\n\n// Find overlapping tasks\nconst findOverlappingTasks = (tasks: Period[]): [Period, Period][] =\u003e {\n  const overlaps: [Period, Period][] = [];\n  for (let i = 0; i \u003c tasks.length; i++) {\n    for (let j = i + 1; j \u003c tasks.length; j++) {\n      if (tasks[i].overlapsWith(tasks[j])) {\n        overlaps.push([tasks[i], tasks[j]]);\n      }\n    }\n  }\n  return overlaps;\n};\n\nconst overlappingTasks = findOverlappingTasks(tasks);\nconsole.log(`There are ${overlappingTasks.length} overlapping tasks in the project.`);\n\n// Calculate project progress\nconst calculateProgress = (currentDate: Date): number =\u003e {\n  const daysPassed = new Period(projectTimeline.getStartDate(), currentDate, Precision.DAY).getDaysInInterval();\n  const totalDays = projectTimeline.getDaysInInterval();\n  return (daysPassed / totalDays) * 100;\n};\n\nconst currentProgress = calculateProgress(new Date('2023-06-15'));\nconsole.log(`Project progress: ${currentProgress.toFixed(2)}%`);\n```\n\n#### **5. Subscription Billing Cycle Management**\nUse the Period class to manage subscription periods and calculate renewal dates.\n``` typescript\nimport { Period, Precision, addToDate } from 'chronos-ts';\n\nclass Subscription {\n  constructor(public startDate: Date, public plan: 'monthly' | 'annual') {}\n\n  getCurrentPeriod(): Period {\n    const endDate = addToDate(this.startDate, 1, this.plan === 'monthly' ? Precision.MONTH : Precision.YEAR);\n    return new Period(this.startDate, endDate, Precision.DAY);\n  }\n\n  isActive(date: Date = new Date()): boolean {\n    return this.getCurrentPeriod().contains(date);\n  }\n\n  getRenewalDate(): Date {\n    return this.getCurrentPeriod().getEndDate();\n  }\n\n  renew(): void {\n    this.startDate = this.getRenewalDate();\n  }\n}\n\nconst monthlySubscription = new Subscription(new Date('2023-01-01'), 'monthly');\nconsole.log(`Monthly subscription active: ${monthlySubscription.isActive()}`);\nconsole.log(`Monthly subscription renewal date: ${monthlySubscription.getRenewalDate().toDateString()}`);\n\nconst annualSubscription = new Subscription(new Date('2023-01-01'), 'annual');\nconsole.log(`Annual subscription active: ${annualSubscription.isActive()}`);\nconsole.log(`Annual subscription renewal date: ${annualSubscription.getRenewalDate().toDateString()}`);\n\n// Check if a subscription will be active on a future date\nconst futureDate = new Date('2023-12-15');\nconsole.log(`Monthly subscription active on ${futureDate.toDateString()}: ${monthlySubscription.isActive(futureDate)}`);\nconsole.log(`Annual subscription active on ${futureDate.toDateString()}: ${annualSubscription.isActive(futureDate)}`);\n\n// Renew a subscription\nmonthlySubscription.renew();\nconst renewedPeriod = monthlySubscription.getCurrentPeriod();\nconsole.log(`Monthly subscription renewed. New period: ${renewedPeriod.getStartDate().toDateString()} - ${renewedPeriod.getEndDate().toDateString()}`);\n```\n\n#### **6. Employee Shift Management**\n\nUse the `Period` and `Interval` classes to manage employee shifts and calculate overtime.\n\n```typescript\nimport { Period, Interval, Precision, addToDate } from 'chronos-ts';\n\nclass Shift extends Period {\n  constructor(public employee: string, start: Date, end: Date) {\n    super(start, end, Precision.MINUTE);\n  }\n\n  getDuration(): number {\n    return this.getHoursInInterval();\n  }\n\n  isOvertime(): boolean {\n    return this.getDuration() \u003e 8;\n  }\n\n  getOvertimeHours(): number {\n    return Math.max(0, this.getDuration() - 8);\n  }\n}\n\n// Create a week's worth of shifts for an employee\nconst createWeekShifts = (employee: string, startDate: Date): Shift[] =\u003e {\n  const shifts: Shift[] = [];\n  for (let i = 0; i \u003c 5; i++) { // Assuming 5-day work week\n    const shiftStart = addToDate(startDate, i, Precision.DAY);\n    shiftStart.setHours(9, 0, 0, 0); // 9 AM start\n    const shiftEnd = new Date(shiftStart);\n    shiftEnd.setHours(17, 0, 0, 0); // 5 PM end\n    shifts.push(new Shift(employee, shiftStart, shiftEnd));\n  }\n  return shifts;\n};\n\nconst employeeShifts = createWeekShifts('John Doe', new Date('2023-06-19'));\n\n// Calculate total hours worked and overtime\nconst totalHours = employeeShifts.reduce((sum, shift) =\u003e sum + shift.getDuration(), 0);\nconst overtimeHours = employeeShifts.reduce((sum, shift) =\u003e sum + shift.getOvertimeHours(), 0);\n\nconsole.log(`Total hours worked: ${totalHours}`);\nconsole.log(`Overtime hours: ${overtimeHours}`);\n\n// Check for conflicting shifts\nconst hasConflict = (shifts: Shift[]): boolean =\u003e {\n  for (let i = 0; i \u003c shifts.length; i++) {\n    for (let j = i + 1; j \u003c shifts.length; j++) {\n      if (shifts[i].overlapsWith(shifts[j])) {\n        return true;\n      }\n    }\n  }\n  return false;\n};\n\nconsole.log(`Shifts have conflicts: ${hasConflict(employeeShifts)}`);\n```\n\n#### **7. Travel Itinerary Planning**\nUse the `Period` class to manage travel itineraries and check for scheduling conflicts.\n``` typescript\nimport { Period, Precision, addToDate } from 'chronos-ts';\n\nclass TravelEvent extends Period {\n  constructor(public description: string, start: Date, end: Date) {\n    super(start, end, Precision.MINUTE);\n  }\n}\n\nclass Itinerary {\n  events: TravelEvent[] = [];\n\n  addEvent(event: TravelEvent): void {\n    if (this.hasConflict(event)) {\n      throw new Error('Event conflicts with existing events');\n    }\n    this.events.push(event);\n  }\n\n  hasConflict(newEvent: TravelEvent): boolean {\n    return this.events.some(event =\u003e event.overlapsWith(newEvent));\n  }\n\n  getDuration(): number {\n    if (this.events.length === 0) return 0;\n    const start = this.events.reduce((min, e) =\u003e e.getStartDate() \u003c min ? e.getStartDate() : min, this.events[0].getStartDate());\n    const end = this.events.reduce((max, e) =\u003e e.getEndDate() \u003e max ? e.getEndDate() : max, this.events[0].getEndDate());\n    return new Period(start, end, Precision.HOUR).getDaysInInterval();\n  }\n}\n\n// Create a travel itinerary\nconst itinerary = new Itinerary();\n\n// Add events to the itinerary\ntry {\n  itinerary.addEvent(new TravelEvent('Flight to Paris', new Date('2023-07-01 10:00'), new Date('2023-07-01 12:00')));\n  itinerary.addEvent(new TravelEvent('Hotel Check-in', new Date('2023-07-01 14:00'), new Date('2023-07-01 15:00')));\n  itinerary.addEvent(new TravelEvent('Eiffel Tower Visit', new Date('2023-07-02 10:00'), new Date('2023-07-02 13:00')));\n  itinerary.addEvent(new TravelEvent('Louvre Museum', new Date('2023-07-03 09:00'), new Date('2023-07-03 12:00')));\n  itinerary.addEvent(new TravelEvent('Flight to Rome', new Date('2023-07-04 15:00'), new Date('2023-07-04 17:00')));\n} catch (error) {\n  console.error('Error creating itinerary:', error.message);\n}\n\nconsole.log(`Itinerary duration: ${itinerary.getDuration()} days`);\n\n// Try to add a conflicting event\ntry {\n  itinerary.addEvent(new TravelEvent('Conflicting Event', new Date('2023-07-01 11:00'), new Date('2023-07-01 13:00')));\n} catch (error) {\n  console.log('Caught conflicting event:', error.message);\n}\n```\n\n## Contributing 🤝\nContributions, issues and feature requests are welcome. After cloning \u0026 setting up project locally, you can just submit a PR to this repo and it will be deployed once it's accepted. There is a list of TODOs in the [TODO.md](TODO.md) file. The project is still in its early stages, so there are plenty of opportunities to contribute.\n\n## License 📝\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgements 🙏\n- [spatie/period](https://github.com/spatie/period)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhendurhance%2Fchronos-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhendurhance%2Fchronos-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhendurhance%2Fchronos-ts/lists"}