Skip to content

Instantly share code, notes, and snippets.

@jrhames
Last active January 19, 2023 03:12
Show Gist options
  • Save jrhames/5200024 to your computer and use it in GitHub Desktop.
Save jrhames/5200024 to your computer and use it in GitHub Desktop.
Holidays plugin for Moment.JS
//## Moment.JS Holiday Plugin
//
//Usage:
// Call .holiday() from any moment object. If date is a US Federal Holiday, name of the holiday will be returned.
// Otherwise, return nothing.
//
// Example:
// `moment('12/25/2013').holiday()` will return "Christmas Day"
//
//Holidays:
// You can configure holiday bellow. The 'M' stands for Month and represents fixed day holidays.
// The 'W' stands for Week, and represents holidays with date based on week day rules.
// Example: '10/2/1' Columbus Day (Second monday of october).
//
//License:
// Copyright (c) 2013 [Jr. Hames](http://jrham.es) under [MIT License](http://opensource.org/licenses/MIT)
(function() {
var moment;
moment = typeof require !== "undefined" && require !== null ? require("moment") : this.moment;
//Holiday definitions
var _holidays = {
'M': {//Month, Day
'01/01': "New Year's Day",
'07/04': "Independence Day",
'11/11': "Veteran's Day",
'11/28': "Thanksgiving Day",
'11/29': "Day after Thanksgiving",
'12/24': "Christmas Eve",
'12/25': "Christmas Day",
'12/31': "New Year's Eve"
},
'W': {//Month, Week of Month, Day of Week
'1/3/1': "Martin Luther King Jr. Day",
'2/3/1': "Washington's Birthday",
'5/5/1': "Memorial Day",
'9/1/1': "Labor Day",
'10/2/1': "Columbus Day",
'11/4/4': "Thanksgiving Day"
}
};
moment.fn.holiday = function() {
var diff = 1+ (0 | (this._d.getDate() - 1) / 7),
memorial = (this._d.getDay() === 1 && (this._d.getDate() + 7) > 30) ? "5" : null;
return (_holidays['M'][this.format('MM/DD')] || _holidays['W'][this.format('M/'+ (memorial || diff) +'/d')]);
};
if ((typeof module !== "undefined" && module !== null ? module.exports : void 0) != null) {
module.exports = moment;
}
}(this));
@ihomecall
Copy link

I need a function to return the specific date for a given holiday name as input -:)

@billyshall
Copy link

Nice! Thanks!

@takuyashim
Copy link

I love it ! :)

It looks like we won't be able to use the format on the example near future - moment('12/25/2013'). It still works but it gets warning. I just squeezed non-format date instead and it works without a warning message.
moment/moment#1407

@baburdick
Copy link

It appears there's also a bug in this code that excludes both the 4th and the 5th Monday when May starts on a Saturday (e.g. 2021-05).

@baburdick
Copy link

Github fooled me and made me think I'd posted my first comment twice. Deleting one of the "copies" deleted the actual comment. Here's a loose reconstruction:

Thanksgiving Day and the Day after Thanksgiving don't fall on numerically consistent dates. Thanksgiving is always on the fourth Thursday in November. Their expression in the 'M' sub-hash above will only appear correct 2 out of every 14 years. They're wrong for 2016.

Memorial Day is the last Monday in May, not necessarily the 5th Monday. Whenever May starts on a Tuesday, Wednesday, Thursday, or Friday, Memorial Day will fall on the 4th Monday of the month. Being able to express a "last" n-day of the month would be useful and would fix this problem, e.g. '5/-1/1'.

@MichalKlacko
Copy link

We tested with this service(https://www.timeanddate.com/holidays/us/2017#!hol=9) for few years ahead and it seems to be fixed.

@imraheel
Copy link

if anyone want to use it as a function

function checkIsHoliday(date) {
	var _holidays = {
        'M': {//Month, Day
            '01/01': "New Year's Day",
            '07/04': "Independence Day",
            '11/11': "Veteran's Day",
            '11/28': "Thanksgiving Day",
            '11/29': "Day after Thanksgiving",
            '12/24': "Christmas Eve",
            '12/25': "Christmas Day",
            '12/31': "New Year's Eve"
        },
        'W': {//Month, Week of Month, Day of Week
            '1/3/1': "Martin Luther King Jr. Day",
            '2/3/1': "Washington's Birthday",
            '5/5/1': "Memorial Day",
            '9/1/1': "Labor Day",
            '10/2/1': "Columbus Day",
            '11/4/4': "Thanksgiving Day"
        }
    };
	var diff = 1+ (0 | (new Date(date).getDate() - 1) / 7);
	var memorial = (new Date(date).getDay() === 1 && (new Date(date).getDate() + 7) > 30) ? "5" : null;
		
	return (_holidays['M'][moment(date).format('MM/DD')] || _holidays['W'][moment(date).format('M/'+ (memorial || diff) +'/d')]);
    }

@paveltyk
Copy link

👍

@jrhames The thanksgiving day appears both in 'M' and 'W' hashes. Is this correct? https://gist.github.com/jrhames/5200024#file-moment-holidays-js-L28

@kodie
Copy link

kodie commented Jul 17, 2017

I've created a plugin for moment that takes care of all your holiday handling and calculating needs: https://github.com/kodie/moment-holiday

My isHoliday() function accomplishes exactly what @jrhames's gist was attempting to do accurately (@baburdick pointed out that this gist doesn't accurately figure out when Thanksgiving or Memorial day is)

For example:

moment('2017-12-25').isHoliday();
//Christmas Day

Also, my holiday() function does exactly what @ihomecall was needing.

For example:

moment().holiday('Memorial Day');
//moment("2017-05-29T00:00:00.000")

Let me know what you think!

@maliu1970
Copy link

I want to get the full list of the national holidays (names) how can I use this?

@misterjuicebox
Copy link

@kodie, I tried to use your plugin on my Angular 2 app and I couldn’t get it to work. Any idea why? I got it to work on my Hugo project and it’s great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment