Skip to content

A Luxon plugin for calculating and manipulating business days and holidays.

License

Notifications You must be signed in to change notification settings

amaidah/luxon-business-days

Repository files navigation

Luxon Business Days

npm CircleCI codecov luxon-business-days npm jsDelivr hits (npm)

Luxon Business Days is a Luxon plugin for calculating and manipulating business days.

Inspired by moment-business-days.

Features

  • Add business days to a standard luxon DateTime instance. For instance, to calculate the arrival date of a shipment.
  • Customizable and extendable. Configure the business working days and holidays of your business.
  • Uses holiday "matcher functions" avoiding the need to manually maintain and update holiday date configs every year.

Install

Versions

Package versions 3+ supports luxon 3+.

For luxon ^1.X, check out 2.8.3

Via NPM

Already using luxon:

yarn add luxon-business-days
- import { DateTime } from 'luxon';
+ import { DateTime } from 'luxon-business-days';
// Use DateTime as normal

Not already using luxon:

yarn add luxon luxon-business-days
import { DateTime } from 'luxon-business-days';
// Use DateTime as normal

Via Browser Script

<script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luxon-business-days/dist/index.js"></script>

Make sure luxon script is loaded before luxon-business-days. For production use, it is recommended to tag a version in the script url like so:

https://cdn.jsdelivr.net/npm/luxon-business-days@2.7.0/dist/index.js
<head> 
  <script src="https://cdn.jsdelivr.net/npm/luxon@1.25.0/build/global/luxon.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/luxon-business-days/dist/index.js"></script>
</head> 

<body> 
  <script>
    let dt = luxon.DateTime.local();
    const nextBizDay = dt.plusBusiness();

    console.log(nextBizDay.toLocaleString());
  </script>
</body> 

Config

Default business days:

  • Monday
  • Tuesday
  • Wednesday
  • Thursday
  • Friday

Default holidays (aka shipping holidays via UPS):

  • New Year's Day
  • Easter Day
  • Memorial Day
  • Independance Day
  • Labor Day
  • Thanksgiving Day
  • Christmas Day

Configure business days

import { DateTime } from 'luxon-business-days';

const dt = DateTime.local();

// [Mon, Thur, Fri, Sun]
const awesomeFourDayBusinessWeek = [1, 4, 5, 7];

dt.setupBusiness({ businessDays: awesomeFourDayBusinessWeek });

Configure holidays

Pick from available holiday matchers:

import { DateTime } from 'luxon-business-days';

const dt = DateTime.local();
const { availableHolidayMatchers } = dt;
const myCompanyIsNoFun = [
  availableHolidayMatchers.isNewYearsDay,
  availableHolidayMatchers.isChristmasDay,
];

dt.setupBusiness({ holidayMatchers: myCompanyIsNoFun });

No holidays:

import { DateTime } from 'luxon-business-days';

const dt = DateTime.local();

dt.setupBusiness({ holidayMatchers: [] });
// Congrats, you will successfuly get everyone to quit

Custom holiday matchers:

A holiday matcher is simply a function that takes in a DateTime instance and returns a boolean. This allows you to algorithmically determine what is considered a holiday without requiring a hardcoded list of dates that are updated and maintained annually.

It is easy to write a basic matcher:

import { DateTime } from 'luxon-business-days';

/**
 * @param {DateTime} - An instance of DateTime.
 * @returns {boolean}
 */
const isCelebratingKobe = function(inst) {
  // Commemorate the day Kobe died
  const kobeRIP = DateTime.fromObject({ month: 1, day: 26 });

  // Celebrate Kobe Day
  const kobeDay = DateTime.fromObject({ month: 8, day: 24 });

  // Matches the following two days regardless of year
  return +inst === +kobeRIP || +inst === +kobeDay;
};

const dt = DateTime.local();
const myHolidays = [
  dt.availableHolidayMatchers.isNewYearsDay,
  dt.availableHolidayMatchers.isChristmasDay,
  isCelebratingKobe,
];

dt.setupBusiness({ holidayMatchers: myHolidays });
// Congrats, now your business will consider New Years, 
// Christmas, and the two Kobe days as holidays.

Tip: When writing custom holiday matchers, it is probably better to avoid harcoding years or dates and instead programatically generating holidays. Take a look at the provided matchers for ideas.

Usage

Basic:

import { DateTime } from 'luxon-business-days';

// Day before July 4
let dt = DateTime.local(2019, 7, 3);

dt = dt.plusBusiness(); // 7/5/19 - Friday
dt = dt.plusBusiness({ days: 2 }); // 7/9/19 - Tuesday (Skipped through Saturday/Sunday)
dt = dt.minusBusiness({ days: 2 }); // back to 7/5/19
dt = dt.minusBusiness({ days: -2 }) // back to 7/9/19
dt = dt.plusBusiness({ days: -2 }); // back to 7/5/19

// Now do what you normally would with a DateTime instance.

Passing additional arguments to matchers:

Perhaps you need to calculate regional holidays manually and want to pass extra information to your custom holiday matchers.

import { DateTime } from 'luxon-business-days';

/**
 * @param {DateTime} - An instance of DateTime.
 * @param {string} region - An example extra param.
 * @param {Object} someStuff - An example extra param.
 * @returns {boolean}
 */
const someCustomRegionalMatcher = (inst, region, someStuff) => {
  // does some matching based on region and data in someStuff
}

/**
 * @param {DateTime} - An instance of DateTime.
 * @returns {boolean}
 */
const anotherCustomMatcher = inst => {
  // does some matching, but doesn't need additional info
}

let dt = DateTime.local();
const myHolidays = [
  someCustomRegionalMatcher,
  anotherCustomMatcher,
];

dt.setupBusiness({ holidayMatchers: myHolidays });

// Pass any additional argument to all your matchers
dt.isHoliday('middle-america', {some: 'stuff'});

Examples

API

Members

DateTimeDateTime

Functions

getEasterMonthAndDay(year)Array.<number>

Returns the month and day of Easter for a given year.

DateTime ⇐ DateTime

Kind: global variable
Extends: DateTime

dateTime.availableHolidayMatchers : Object

All built-in holiday matchers.

Kind: instance property of DateTime
Extends: DateTime
Properties

Name Type Description
isNewYearsDay function A provided holiday matcher.
isMLKDay function A provided holiday matcher.
isEasterDay function A provided holiday matcher.
isMemorialDay function A provided holiday matcher.
isIndependanceDay function A provided holiday matcher.
isLaborDay function A provided holiday matcher.
isColumbusDay function A provided holiday matcher.
isThanksgivingDay function A provided holiday matcher.
isChristmasDay function A provided holiday matcher.

dateTime.availableHolidayHelpers : Object

Exposes all available holiday helpers to a DateTime instance.

Kind: instance property of DateTime
Extends: DateTime
Properties

Name Type Description
getEasterMonthAndDay function A provided holiday helper function that can be helpful for custom holiday matchers.

dateTime.setupBusiness([businessDays], [holidayMatchers]) ⇐ DateTime

Sets up business days and holiday matchers globally for all DateTime instances.

Kind: instance method of DateTime
Extends: DateTime

Param Type Default Description
[businessDays] Array.<number> DEFAULT_BUSINESS_DAYS The working business days for the business.
[holidayMatchers] Array.<function()> DEFAULT_HOLIDAY_MATCHERS The holiday matchers used to check if a particular day is a holiday for the business.

dateTime.clearBusinessSetup() ⇐ DateTime

Clears business setup globally from all DateTime instances.

Kind: instance method of DateTime
Extends: DateTime

dateTime.isHoliday([...args]) ⇒ boolean

Checks if DateTime instance is a holiday by checking against all holiday matchers.

Kind: instance method of DateTime
Extends: DateTime

Param Type Description
[...args] * Any additional arguments to pass through to each holiday matcher.

dateTime.isBusinessDay() ⇒ boolean

Checks if DateTime instance is a business day.

Kind: instance method of DateTime
Extends: DateTime

dateTime.plusBusiness([days]) ⇒ DateTime

Adds business days to an existing DateTime instance.

Kind: instance method of DateTime
Extends: DateTime

Param Type Default Description
[days] number 1 The number of business days to add.

dateTime.minusBusiness([days]) ⇒ DateTime

Subtracts business days to an existing DateTime instance.

Kind: instance method of DateTime
Extends: DateTime

Param Type Default Description
[days] number 1 The number of business days to subtract.

getEasterMonthAndDay(year) ⇒ Array.<number>

Returns the month and day of Easter for a given year.

Kind: global function
Returns: Array.<number> - Returns month and day via [month, day].

Param Type
year number