date-holidays
Advanced tools
Comparing version 1.1.1 to 1.2.0
# CHANGELOG | ||
v1.2.0 | ||
- Parser is moved into new repo [date-holidays-parser](https://github.com/commenthol/date-holidays-parser) | ||
- Minimizing data files and build requires `--min` on `holidays2json` script | ||
- New Countries | ||
- Greenland | ||
- Domenica | ||
- Curacao | ||
- Vatikan City | ||
- Ukraine | ||
- Slovenia | ||
- Serbia | ||
- Moldavia | ||
- Slovakia | ||
- Svalbard & Jan Mayen | ||
- San Marino | ||
- Macedonia | ||
- Kosovo | ||
- Gibraltar | ||
- Moving French oversee departments to own Country-Code | ||
- Fix Bosnia and Herzegovina orthodox christmas and names | ||
v1.1.1 | ||
@@ -4,0 +25,0 @@ - Adding ES Andalucía, Andalucía |
/** | ||
* @copyright 2016 (c) commenthol | ||
* @copyright 2015-present (c) commenthol | ||
* @license ISC | ||
@@ -8,19 +8,5 @@ */ | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
var Parser = require('date-holidays-parser'); | ||
var data = require('../data/holidays.json'); | ||
var _ = { | ||
merge: require('lodash.merge'), | ||
omit: require('lodash.omit'), | ||
set: require('lodash.set') | ||
}; | ||
var _require = require('./internal/utils'), | ||
toYear = _require.toYear, | ||
toDate = _require.toDate; | ||
var Data = require('./Data'); | ||
var DateFn = require('./DateFn'); | ||
var TYPES = ['public', 'bank', 'school', 'optional', 'observance']; | ||
/** | ||
@@ -46,430 +32,9 @@ * @class | ||
} | ||
Parser.apply(this, [data, country, state, region, opts]); | ||
this.init(country, state, region, opts); | ||
} | ||
module.exports = Holidays; | ||
Holidays.prototype = { | ||
/** | ||
* initialize holidays for a country/state/region | ||
* @param {String|Object} country - if object use `{ country: {String}, state: {String}, region: {String} }` | ||
* @param {String} [state] - specifies state | ||
* @param {String} [region] - specifies region | ||
* @param {Object} [opts] - options | ||
* @param {Array|String} opts.languages - set language(s) with ISO 639-1 shortcodes | ||
* @param {String} opts.timezone - set timezone | ||
* @param {Array} opts.types - holiday types to consider | ||
* @param {Object} [opts.data] - holiday data object - see data/holidays.json | ||
*/ | ||
init: function init(country, state, region, opts) { | ||
var self = this; | ||
Holidays.prototype = Object.create(Parser.prototype); | ||
Holidays.prototype.constructor = Holidays; | ||
// reset settings | ||
this.__conf = null; | ||
this.holidays = {}; | ||
this.setLanguages(); | ||
if ((typeof region === 'undefined' ? 'undefined' : _typeof(region)) === 'object') { | ||
opts = region; | ||
region = null; | ||
} else if ((typeof state === 'undefined' ? 'undefined' : _typeof(state)) === 'object') { | ||
opts = state; | ||
state = null; | ||
} | ||
opts = opts || {}; | ||
this._setTypes(opts.types); | ||
this.__conf = Data.splitName(country, state, region); | ||
if (this.__conf) { | ||
this.__data = new Data(this.__conf, opts.data); | ||
if (opts.languages) { | ||
this.setLanguages(opts.languages); | ||
} else { | ||
this.setLanguages(this.__data.getLanguages()); | ||
} | ||
var holidays = this.__data.getHolidays(); | ||
if (holidays) { | ||
this.__timezone = opts.timezone || this.__data.getTimezones()[0]; | ||
Object.keys(holidays).forEach(function (rule) { | ||
self.setHoliday(rule, holidays[rule]); | ||
}); | ||
return true; | ||
} | ||
} else { | ||
this.__data = new Data(null, opts.data); | ||
} | ||
}, | ||
/** | ||
* set (custom) holiday | ||
* @param {String} rule - rule for holiday (check supported grammar) or date in ISO Format, e.g. 12-31 for 31th Dec | ||
* @param {Object|String} [opts] - holiday options, if String then opts is used as name | ||
* @param {Object} opts.name - translated holiday names e.g. `{ en: 'name', es: 'nombre', ... }` | ||
* @param {String} opts.type - holiday type `public|bank|school|observance` | ||
* @throws {TypeError} | ||
* @return {Boolean} if holiday could be set returns `true` | ||
*/ | ||
setHoliday: function setHoliday(rule, opts) { | ||
// remove days | ||
if (opts === false) { | ||
if (this.holidays[rule]) { | ||
this.holidays[rule] = false; | ||
return true; | ||
} | ||
return false; | ||
} | ||
// assign a name to rule | ||
if (!opts || typeof opts === 'string') { | ||
opts = opts || rule; | ||
var lang = this.getLanguages()[0]; | ||
opts = _.set({ type: 'public' }, ['name', lang], opts); | ||
} | ||
// convert active properties to Date | ||
if (opts.active) { | ||
if (!Array.isArray(opts.active)) { | ||
throw TypeError('.active is not of type Array: ' + rule); | ||
} | ||
opts.active = opts.active.map(function (a) { | ||
var from = toDate(a.from); | ||
var to = toDate(a.to); | ||
if (!(from || to)) { | ||
throw TypeError('.active needs .from or .to property: ' + rule); | ||
} | ||
return { from: from, to: to }; | ||
}); | ||
} | ||
// check for supported type | ||
if (!this._hasType(opts.type)) { | ||
return false; | ||
} | ||
this.holidays[rule] = opts; | ||
var fn = new DateFn(rule, this.holidays); | ||
if (fn.ok) { | ||
this.holidays[rule].fn = fn; | ||
return true; | ||
} else { | ||
// throw Error('could not parse rule: ' + rule) // NEXT | ||
console.log('could not parse rule: ' + rule); | ||
} | ||
return false; | ||
}, | ||
/** | ||
* get all holidays for `year` with names using prefered `language` | ||
* @param {String|Date} [year] - if omitted current year is choosen | ||
* @param {String} [language] - ISO 639-1 code for language | ||
* @return {Array} of found holidays in given year sorted by Date: | ||
* ``` | ||
* {String} date - ISO Date String of (start)-date in local format | ||
* {Date} start - start date of holiday | ||
* {Date} end - end date of holiday | ||
* {String} name - name of holiday using `language` (if available) | ||
* {String} type - type of holiday `public|bank|school|observance` | ||
* ``` | ||
*/ | ||
getHolidays: function getHolidays(year, language) { | ||
year = toYear(year); | ||
var _this = this; | ||
var arr = []; | ||
var langs = this.getLanguages(); | ||
if (language) { | ||
langs.unshift(language); | ||
} | ||
Object.keys(this.holidays).forEach(function (rule) { | ||
if (_this.holidays[rule].fn) { | ||
_this._dateByRule(year, rule).forEach(function (o) { | ||
arr.push(_this._translate(o, langs)); | ||
}); | ||
} | ||
}); | ||
// sort by date | ||
arr = arr.sort(function (a, b) { | ||
return +a.start - +b.start; | ||
}).map(function (a, i) { | ||
var b = arr[i + 1]; | ||
if (b && a.name === b.name && +a.start === +b.start) { | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = TYPES[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var type = _step.value; | ||
if (type === a.type || type === b.type) { | ||
a.filter = true; | ||
b.type = type; | ||
break; | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator.return) { | ||
_iterator.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
} | ||
return a; | ||
}).filter(function (a) { | ||
if (!a.filter) return a; | ||
}); | ||
return arr; | ||
}, | ||
/** | ||
* check whether `date` is a holiday or not | ||
* @param {Date} [date] | ||
* @return {Object} holiday: | ||
* ``` | ||
* {String} date - ISO Date String of (start)-date in local format | ||
* {Date} start - start date of holiday | ||
* {Date} end - end date of holiday | ||
* {String} name - name of holiday using `language` (if available) | ||
* {String} type - type of holiday `public|bank|school|observance` | ||
* ``` | ||
*/ | ||
isHoliday: function isHoliday(date) { | ||
date = date || new Date(); | ||
var hd; | ||
var year = toYear(date); | ||
var rules = Object.keys(this.holidays); | ||
for (var i in rules) { | ||
hd = [].concat(this._dateByRule(year, rules[i])); | ||
for (var j in hd) { | ||
if (hd[j] && date >= hd[j].start && date < hd[j].end) { | ||
return this._translate(hd[j]); | ||
} | ||
} | ||
} | ||
return false; | ||
}, | ||
/** | ||
* Query for available Countries, States, Regions | ||
* @param {String} [country] | ||
* @param {String} [state] | ||
* @param {String} [lang] - ISO-639 language shortcode | ||
* @return {Object} shortcode, name pairs of supported countries, states, regions | ||
*/ | ||
query: function query(country, state, lang) { | ||
var o = Data.splitName(country, state); | ||
if (!o || !o.country) { | ||
return this.getCountries(lang); | ||
} else if (!o.state) { | ||
return this.getStates(o.country, lang); | ||
} else { | ||
return this.getRegions(o.country, o.state, lang); | ||
} | ||
}, | ||
/** | ||
* get supported countries | ||
* @param {String} [lang] - ISO-639 language shortcode | ||
* @return {Object} shortcode, name pairs of supported countries | ||
* ```js | ||
* { AD: 'Andorra', | ||
* US: 'United States' } | ||
* ``` | ||
*/ | ||
getCountries: function getCountries(lang) { | ||
return this.__data.getCountries(lang); | ||
}, | ||
/** | ||
* get supported states for a given country | ||
* @param {String} country - shortcode of country | ||
* @param {String} [lang] - ISO-639 language shortcode | ||
* @return {Object} shortcode, name pairs of supported states, regions | ||
* ```js | ||
* { al: 'Alabama', ... | ||
* wy: 'Wyoming' } | ||
* ``` | ||
*/ | ||
getStates: function getStates(country, lang) { | ||
return this.__data.getStates(country, lang); | ||
}, | ||
/** | ||
* get supported regions for a given country, state | ||
* @param {String} country - shortcode of country | ||
* @param {String} state - shortcode of state | ||
* @param {String} [lang] - ISO-639 language shortcode | ||
* @return {Object} shortcode, name pairs of supported regions | ||
* ```js | ||
* { no: 'New Orleans' } | ||
* ``` | ||
*/ | ||
getRegions: function getRegions(country, state, lang) { | ||
return this.__data.getRegions(country, state, lang); | ||
}, | ||
/** | ||
* get timezones for country, state, region | ||
* @return {Array} of {String}s containing the timezones | ||
*/ | ||
getTimezones: function getTimezones() { | ||
if (this.__data) { | ||
return this.__data.getTimezones(); | ||
} | ||
}, | ||
/** | ||
* sets timezone | ||
* @param {String} timezone - see `moment-timezone` | ||
* if `timezone` is `undefined` then all dates are considered local dates | ||
*/ | ||
setTimezone: function setTimezone(timezone) { | ||
this.__timezone = timezone; | ||
}, | ||
/** | ||
* get languages for selected country, state, region | ||
* @return {Array} containing ISO 639-1 language shortcodes | ||
*/ | ||
getLanguages: function getLanguages() { | ||
return this.__languages; | ||
}, | ||
/** | ||
* set language(s) for holiday names | ||
* @param {Array|String} language | ||
* @return {Array} set languages | ||
*/ | ||
setLanguages: function setLanguages(language) { | ||
if (typeof language === 'string') { | ||
language = [language]; | ||
} | ||
var tmp = {}; | ||
this.__languages = [].concat(language, 'en', this.__conf ? this.__data.getLanguages() : []).filter(function (l) { | ||
// filter out duplicates | ||
if (!l || tmp[l]) { | ||
return false; | ||
} | ||
tmp[l] = 1; | ||
return true; | ||
}); | ||
}, | ||
/** | ||
* get default day off as weekday | ||
* @return {String} weekday of day off | ||
*/ | ||
getDayOff: function getDayOff() { | ||
if (this.__conf) { | ||
return this.__data.getDayOff(); | ||
} | ||
}, | ||
/** | ||
* @private | ||
* @param {Number} year | ||
* @param {String} rule | ||
*/ | ||
_dateByRule: function _dateByRule(year, rule) { | ||
var _rule = this.holidays[rule]; | ||
var dates = _rule.fn.inYear(year).get(this.__timezone); | ||
dates = dates.map(function (date) { | ||
var odate = _.merge({}, _.omit(date, ['substitute']), _.omit(_rule, ['fn', 'enable', 'disable', 'substitute', 'active'])); | ||
if (_rule.substitute && date.substitute) { | ||
odate.substitute = true; | ||
} | ||
return odate; | ||
}); | ||
return dates; | ||
}, | ||
/** | ||
* translate holiday object `o` to a language | ||
* @private | ||
* @param {Object} o | ||
* @param {Array} langs - languages for translation | ||
* @return {Object} translated holiday object | ||
*/ | ||
_translate: function _translate(o, langs) { | ||
if (o && _typeof(o.name) === 'object') { | ||
langs = langs || this.getLanguages(); | ||
var name; | ||
var subst; | ||
for (var i in langs) { | ||
if (name = o.name[langs[i]]) { | ||
o.name = name; | ||
break; | ||
} | ||
} | ||
if (o.substitute) { | ||
for (i in langs) { | ||
subst = this.__data.getSubstitueNames(); | ||
if (name = subst[langs[i]]) { | ||
o.name += ' (' + name + ')'; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
return o; | ||
}, | ||
/** | ||
* set holiday types | ||
* @private | ||
* @param {Array} [t] - holiday types | ||
* @return {Object} new array of types | ||
*/ | ||
_setTypes: function _setTypes(t) { | ||
t = t || []; | ||
var types = {}; | ||
TYPES.map(function (type) { | ||
for (var i in t) { | ||
if (type !== t[i]) { | ||
return; | ||
} | ||
} | ||
types[type] = 1; | ||
}); | ||
this.__types = types; | ||
}, | ||
/** | ||
* check for supported holiday type | ||
* @private | ||
* @param {String} type | ||
* @return {Boolean} | ||
*/ | ||
_hasType: function _hasType(type) { | ||
return !!this.__types[type]; | ||
} | ||
}; | ||
module.exports = Holidays; |
{ | ||
"name": "date-holidays", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"description": "worldwide holidays", | ||
@@ -24,2 +24,3 @@ "keywords": [ | ||
"main": "lib", | ||
"module": "src", | ||
"jsnext:main": "src", | ||
@@ -39,15 +40,13 @@ "bin": { | ||
"all": "npm run clean && npm i && npm run lint && npm run transpile && npm run yaml && npm test && npm pack", | ||
"clean": "rimraf coverage lib node_modules", | ||
"cover": "istanbul cover _mocha --report lcov --report text -- -R dot --check-leaks test/*.mocha.js", | ||
"lint": "eslint --quiet '**/*.js'", | ||
"clean": "rimraf lib node_modules", | ||
"lint": "eslint '**/*.js'", | ||
"test": "mocha", | ||
"test:all": "npm run yaml && mocha test/all.mocha.js", | ||
"test:ci": "npm run transpile && npm run yaml && npm test", | ||
"transpile": "babel -d lib src", | ||
"watch": "watch-run -p data/countries/*.yaml npm run yaml", | ||
"yaml": "node scripts/holidays2json.js", | ||
"zuul": "zuul test/Holidays.mocha.js" | ||
"yaml": "node scripts/holidays2json.js" | ||
}, | ||
"babel": { | ||
"presets": [ | ||
"es2015" | ||
"env" | ||
] | ||
@@ -62,19 +61,14 @@ }, | ||
"dependencies": { | ||
"astronomia": "^1.3.5", | ||
"babelify": "^8.0.0", | ||
"caldate": "^1.0.0", | ||
"date-chinese": "^1.0.2", | ||
"date-easter": "^0.2.2", | ||
"js-yaml": "^3.8.4", | ||
"lodash.get": "^4.4.2", | ||
"lodash.merge": "^4.6.0", | ||
"date-holidays-parser": "^1.2.0", | ||
"js-yaml": "^3.10.0", | ||
"lodash.omit": "^4.5.0", | ||
"lodash.set": "^4.3.2", | ||
"moment-timezone": "^0.5.13", | ||
"lodash.pick": "^4.4.0", | ||
"prepin": "^1.0.1" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.26.0", | ||
"babel-core": "^6.23.1", | ||
"babel-preset-es2015": "^6.22.0", | ||
"babel-preset-env": "^1.6.0", | ||
"babel-register": "^6.23.0", | ||
"babelify": "^8.0.0", | ||
"core-js": "^2.5.0", | ||
@@ -88,7 +82,5 @@ "eslint": "^4.10.0", | ||
"hashtree": "^0.7.0", | ||
"istanbul": "^0.4.5", | ||
"mocha": "^4.0.1", | ||
"rimraf": "^2.5.4", | ||
"serialize-to-js": "^1.0.0", | ||
"zuul": "^3.11.1" | ||
"serialize-to-js": "^1.0.0" | ||
}, | ||
@@ -95,0 +87,0 @@ "engines": { |
@@ -57,3 +57,3 @@ # date-holidays | ||
``` | ||
Countries: 111 | ||
Countries: 130 | ||
├── AD: Andorra | ||
@@ -173,2 +173,3 @@ │ └── 07: Andorra la Vella | ||
├── CU: Cuba | ||
├── CW: Curaçao | ||
├── CY: Κύπρος | ||
@@ -200,2 +201,3 @@ ├── CZ: Česká republika | ||
├── DK: Danmark | ||
├── DM: Dominica | ||
├── DO: República Dominicana | ||
@@ -230,3 +232,7 @@ ├── EC: Ecuador | ||
├── GD: Grenada | ||
├── GF: Guyane | ||
├── GG: Guernsey | ||
├── GI: Gibraltar | ||
├── GL: Kalaallit Nunaat | ||
├── GP: Guadeloupe | ||
├── GQ: República de Guinea Ecuatorial | ||
@@ -258,4 +264,9 @@ ├── GR: Ελλάδα | ||
├── MC: Monaco | ||
├── MD: Republica Moldova | ||
│ ├── CA: Cahul | ||
│ └── CU: Chișinău | ||
├── ME: Crna Gora | ||
├── MG: Repoblikan'i Madagasikara | ||
├── MK: Република Македонија | ||
├── MQ: Martinique | ||
├── MT: Malta | ||
@@ -289,6 +300,12 @@ ├── MW: Malawi | ||
├── PY: Paraguay | ||
├── RE: Réunion | ||
├── RO: Romania | ||
├── RS: Република Србија | ||
├── RU: Россия | ||
├── RW: Repubulika y'u Rwanda | ||
├── SE: Sverige | ||
├── SI: Republika Slovenija | ||
├── SJ: Svalbard & Jan Mayen | ||
├── SK: Slovenská republika | ||
├── SM: San Marino | ||
├── SO: Jamhuuriyadda Federaalka Soomaaliya | ||
@@ -306,2 +323,3 @@ │ ├── AW: Awdal | ||
├── TZ: Tanzania | ||
├── UA: Україна | ||
├── UG: Uganda | ||
@@ -363,2 +381,3 @@ ├── US: United States of America | ||
├── UY: Uruguay | ||
├── VA: Stato della Città del Vaticano | ||
├── VE: Venezuela | ||
@@ -374,2 +393,4 @@ │ ├── B: Anzoátegui | ||
├── VN: Cộng hòa Xã hội chủ nghĩa Việt Nam | ||
├── XK: Republika e Kosovës | ||
├── YT: Mayotte | ||
├── ZA: South Africa | ||
@@ -505,9 +526,9 @@ ├── ZM: Zambia | ||
Browser | Version | Notes | ||
--- | --- | --- | ||
Chrome | >=45 | | ||
Firefox | >=45 | | ||
Safari | >=10 | | ||
Edge | >=13 | | ||
IE | >=10 | needs polyfill `core-js/es6` | ||
| Browser | Version | Notes | | ||
| ------- | :-----: | ---------------------------- | | ||
| Chrome | >=45 | | | ||
| Firefox | >=45 | | | ||
| Safari | >=10 | | | ||
| Edge | >=13 | | | ||
| IE | >=10 | needs polyfill `core-js/es6` | | ||
@@ -549,6 +570,8 @@ Please do not forget to set the correct charset! | ||
"scripts": { | ||
"build": "holidays2json --pick US,CA,MX" | ||
"build": "holidays2json --pick US,CA,MX --min" | ||
}, | ||
``` | ||
The `--min` switch removes dependencies which are not required for the countries selected. You may not be able to use the full set of rules in case you want to add custom rules. | ||
Alternatively you may use the `--omit` option. | ||
@@ -592,2 +615,3 @@ | ||
* [date-holidays-ical][date-holidays-ical] | ||
* [date-holidays-parser][date-holidays-parser] | ||
* [Holidays API][Holidays API] | ||
@@ -601,4 +625,5 @@ * [holidays.yaml specification][holidays.yaml specification] | ||
[CONTRIBUTING.md]: ./CONTRIBUTING.md | ||
[holidays.yaml specification]: ./docs/specification.md | ||
[Holidays API]: ./docs/Holidays.md | ||
[holidays.yaml specification]: https://github.com/commenthol/date-holidays/blob/master/docs/specification.md | ||
[Holidays API]: https://github.com/commenthol/date-holidays-parser/blob/master/docs/Holidays.md | ||
[date-holidays-parser]: https://github.com/commenthol/date-holidays-parser | ||
[date-holidays-ical]: https://github.com/commenthol/date-holidays-ical |
@@ -6,9 +6,13 @@ #!/usr/bin/env node | ||
var fs = require('fs') | ||
var resolve = require('path').resolve | ||
var path = require('path') | ||
var resolve = path.resolve | ||
var jsyaml = require('js-yaml') | ||
var PrePin = require('prepin') | ||
var _ = require('lodash') | ||
var _pick = require('lodash.pick') | ||
var _omit = require('lodash.omit') | ||
var REGEX = /^([A-Z]+)\.yaml$/ | ||
var dirParser = path.dirname(require.resolve('date-holidays-parser')) | ||
var config = { | ||
@@ -18,4 +22,4 @@ dirname: resolve(__dirname, '..', 'data'), | ||
factories: [ | ||
resolve(__dirname, '..', 'src', 'CalEventFactory.js'), | ||
resolve(__dirname, '..', 'lib', 'CalEventFactory.js') | ||
resolve(dirParser, '..', 'src', 'CalEventFactory.js'), | ||
resolve(dirParser, '..', 'lib', 'CalEventFactory.js') | ||
] | ||
@@ -68,5 +72,5 @@ } | ||
if (this.opts.pick) { | ||
obj.holidays = _.pick(obj.holidays, this.opts.pick) | ||
obj.holidays = _pick(obj.holidays, this.opts.pick) | ||
} else if (this.opts.omit) { | ||
obj.holidays = _.omit(obj.holidays, this.opts.omit) | ||
obj.holidays = _omit(obj.holidays, this.opts.omit) | ||
} | ||
@@ -76,4 +80,5 @@ | ||
this.holidays = obj | ||
this.prepin() | ||
if (this.opts.min) this.prepin() | ||
return this | ||
@@ -88,2 +93,5 @@ }, | ||
}, | ||
/** | ||
* modify the factories to require only the minimum required packages | ||
*/ | ||
prepin: function () { | ||
@@ -107,8 +115,9 @@ // reduce final build size | ||
if (i !== -1) { | ||
var list = args[i + 1].toUpperCase().split(',').sort() | ||
var list = (args[i + 1] || '').toUpperCase().split(',').sort() | ||
if (list && list.length) return list | ||
return true | ||
} | ||
} | ||
if (args.indexOf('-h') !== -1 || args.indexOf('--help') !== -1) { | ||
if (getOption('-h') || getOption('--help')) { | ||
console.log([ | ||
@@ -124,2 +133,4 @@ '', | ||
' from holidays.json file', | ||
'-m|--min minimize the package dependencies - e.g. if using webpack or', | ||
' browserify', | ||
'', | ||
@@ -132,3 +143,3 @@ 'NOTE: There are some countries which depend on data of others which', | ||
' "build" : "holidays2json -p US,CA,GU"', | ||
' and run then with `npm run build`', | ||
'and run then with `npm run build`', | ||
'' | ||
@@ -141,3 +152,4 @@ ].join('\n ')) | ||
pick: getOption('--pick') || getOption('-p'), | ||
omit: getOption('--omit') || getOption('-o') | ||
omit: getOption('--omit') || getOption('-o'), | ||
min: getOption('--min') || getOption('-m') | ||
} | ||
@@ -144,0 +156,0 @@ |
/** | ||
* @copyright 2016 (c) commenthol | ||
* @copyright 2015-present (c) commenthol | ||
* @license ISC | ||
@@ -8,13 +8,5 @@ */ | ||
const _ = { | ||
merge: require('lodash.merge'), | ||
omit: require('lodash.omit'), | ||
set: require('lodash.set') | ||
} | ||
const {toYear, toDate} = require('./internal/utils') | ||
const Data = require('./Data') | ||
const DateFn = require('./DateFn') | ||
const Parser = require('date-holidays-parser') | ||
const data = require('../data/holidays.json') | ||
var TYPES = ['public', 'bank', 'school', 'optional', 'observance'] | ||
/** | ||
@@ -40,401 +32,9 @@ * @class | ||
} | ||
Parser.apply(this, [data, country, state, region, opts]) | ||
this.init(country, state, region, opts) | ||
} | ||
module.exports = Holidays | ||
Holidays.prototype = { | ||
/** | ||
* initialize holidays for a country/state/region | ||
* @param {String|Object} country - if object use `{ country: {String}, state: {String}, region: {String} }` | ||
* @param {String} [state] - specifies state | ||
* @param {String} [region] - specifies region | ||
* @param {Object} [opts] - options | ||
* @param {Array|String} opts.languages - set language(s) with ISO 639-1 shortcodes | ||
* @param {String} opts.timezone - set timezone | ||
* @param {Array} opts.types - holiday types to consider | ||
* @param {Object} [opts.data] - holiday data object - see data/holidays.json | ||
*/ | ||
init (country, state, region, opts) { | ||
var self = this | ||
Holidays.prototype = Object.create(Parser.prototype) | ||
Holidays.prototype.constructor = Holidays | ||
// reset settings | ||
this.__conf = null | ||
this.holidays = {} | ||
this.setLanguages() | ||
if (typeof region === 'object') { | ||
opts = region | ||
region = null | ||
} else if (typeof state === 'object') { | ||
opts = state | ||
state = null | ||
} | ||
opts = opts || {} | ||
this._setTypes(opts.types) | ||
this.__conf = Data.splitName(country, state, region) | ||
if (this.__conf) { | ||
this.__data = new Data(this.__conf, opts.data) | ||
if (opts.languages) { | ||
this.setLanguages(opts.languages) | ||
} else { | ||
this.setLanguages(this.__data.getLanguages()) | ||
} | ||
var holidays = this.__data.getHolidays() | ||
if (holidays) { | ||
this.__timezone = opts.timezone || this.__data.getTimezones()[0] | ||
Object.keys(holidays).forEach(function (rule) { | ||
self.setHoliday(rule, holidays[rule]) | ||
}) | ||
return true | ||
} | ||
} else { | ||
this.__data = new Data(null, opts.data) | ||
} | ||
}, | ||
/** | ||
* set (custom) holiday | ||
* @param {String} rule - rule for holiday (check supported grammar) or date in ISO Format, e.g. 12-31 for 31th Dec | ||
* @param {Object|String} [opts] - holiday options, if String then opts is used as name | ||
* @param {Object} opts.name - translated holiday names e.g. `{ en: 'name', es: 'nombre', ... }` | ||
* @param {String} opts.type - holiday type `public|bank|school|observance` | ||
* @throws {TypeError} | ||
* @return {Boolean} if holiday could be set returns `true` | ||
*/ | ||
setHoliday (rule, opts) { | ||
// remove days | ||
if (opts === false) { | ||
if (this.holidays[rule]) { | ||
this.holidays[rule] = false | ||
return true | ||
} | ||
return false | ||
} | ||
// assign a name to rule | ||
if (!opts || typeof opts === 'string') { | ||
opts = opts || rule | ||
var lang = this.getLanguages()[0] | ||
opts = _.set({type: 'public'}, ['name', lang], opts) | ||
} | ||
// convert active properties to Date | ||
if (opts.active) { | ||
if (!Array.isArray(opts.active)) { | ||
throw TypeError('.active is not of type Array: ' + rule) | ||
} | ||
opts.active = opts.active.map((a) => { | ||
let from = toDate(a.from) | ||
let to = toDate(a.to) | ||
if (!(from || to)) { | ||
throw TypeError('.active needs .from or .to property: ' + rule) | ||
} | ||
return {from, to} | ||
}) | ||
} | ||
// check for supported type | ||
if (!this._hasType(opts.type)) { | ||
return false | ||
} | ||
this.holidays[rule] = opts | ||
var fn = new DateFn(rule, this.holidays) | ||
if (fn.ok) { | ||
this.holidays[rule].fn = fn | ||
return true | ||
} else { | ||
// throw Error('could not parse rule: ' + rule) // NEXT | ||
console.log('could not parse rule: ' + rule) | ||
} | ||
return false | ||
}, | ||
/** | ||
* get all holidays for `year` with names using prefered `language` | ||
* @param {String|Date} [year] - if omitted current year is choosen | ||
* @param {String} [language] - ISO 639-1 code for language | ||
* @return {Array} of found holidays in given year sorted by Date: | ||
* ``` | ||
* {String} date - ISO Date String of (start)-date in local format | ||
* {Date} start - start date of holiday | ||
* {Date} end - end date of holiday | ||
* {String} name - name of holiday using `language` (if available) | ||
* {String} type - type of holiday `public|bank|school|observance` | ||
* ``` | ||
*/ | ||
getHolidays (year, language) { | ||
year = toYear(year) | ||
var _this = this | ||
var arr = [] | ||
var langs = this.getLanguages() | ||
if (language) { | ||
langs.unshift(language) | ||
} | ||
Object.keys(this.holidays).forEach(function (rule) { | ||
if (_this.holidays[rule].fn) { | ||
_this._dateByRule(year, rule).forEach(function (o) { | ||
arr.push(_this._translate(o, langs)) | ||
}) | ||
} | ||
}) | ||
// sort by date | ||
arr = arr.sort(function (a, b) { | ||
return (+a.start) - (+b.start) | ||
}) | ||
.map(function (a, i) { | ||
var b = arr[i + 1] | ||
if (b && (a.name === b.name) && (+a.start) === (+b.start)) { | ||
for (var type of TYPES) { | ||
if (type === a.type || type === b.type) { | ||
a.filter = true | ||
b.type = type | ||
break | ||
} | ||
} | ||
} | ||
return a | ||
}) | ||
.filter(function (a) { | ||
if (!a.filter) return a | ||
}) | ||
return arr | ||
}, | ||
/** | ||
* check whether `date` is a holiday or not | ||
* @param {Date} [date] | ||
* @return {Object} holiday: | ||
* ``` | ||
* {String} date - ISO Date String of (start)-date in local format | ||
* {Date} start - start date of holiday | ||
* {Date} end - end date of holiday | ||
* {String} name - name of holiday using `language` (if available) | ||
* {String} type - type of holiday `public|bank|school|observance` | ||
* ``` | ||
*/ | ||
isHoliday (date) { | ||
date = date || new Date() | ||
var hd | ||
var year = toYear(date) | ||
var rules = Object.keys(this.holidays) | ||
for (var i in rules) { | ||
hd = [].concat(this._dateByRule(year, rules[i])) | ||
for (var j in hd) { | ||
if (hd[j] && date >= hd[j].start && date < hd[j].end) { | ||
return this._translate(hd[j]) | ||
} | ||
} | ||
} | ||
return false | ||
}, | ||
/** | ||
* Query for available Countries, States, Regions | ||
* @param {String} [country] | ||
* @param {String} [state] | ||
* @param {String} [lang] - ISO-639 language shortcode | ||
* @return {Object} shortcode, name pairs of supported countries, states, regions | ||
*/ | ||
query (country, state, lang) { | ||
var o = Data.splitName(country, state) | ||
if (!o || !o.country) { | ||
return this.getCountries(lang) | ||
} else if (!o.state) { | ||
return this.getStates(o.country, lang) | ||
} else { | ||
return this.getRegions(o.country, o.state, lang) | ||
} | ||
}, | ||
/** | ||
* get supported countries | ||
* @param {String} [lang] - ISO-639 language shortcode | ||
* @return {Object} shortcode, name pairs of supported countries | ||
* ```js | ||
* { AD: 'Andorra', | ||
* US: 'United States' } | ||
* ``` | ||
*/ | ||
getCountries (lang) { | ||
return this.__data.getCountries(lang) | ||
}, | ||
/** | ||
* get supported states for a given country | ||
* @param {String} country - shortcode of country | ||
* @param {String} [lang] - ISO-639 language shortcode | ||
* @return {Object} shortcode, name pairs of supported states, regions | ||
* ```js | ||
* { al: 'Alabama', ... | ||
* wy: 'Wyoming' } | ||
* ``` | ||
*/ | ||
getStates (country, lang) { | ||
return this.__data.getStates(country, lang) | ||
}, | ||
/** | ||
* get supported regions for a given country, state | ||
* @param {String} country - shortcode of country | ||
* @param {String} state - shortcode of state | ||
* @param {String} [lang] - ISO-639 language shortcode | ||
* @return {Object} shortcode, name pairs of supported regions | ||
* ```js | ||
* { no: 'New Orleans' } | ||
* ``` | ||
*/ | ||
getRegions (country, state, lang) { | ||
return this.__data.getRegions(country, state, lang) | ||
}, | ||
/** | ||
* get timezones for country, state, region | ||
* @return {Array} of {String}s containing the timezones | ||
*/ | ||
getTimezones () { | ||
if (this.__data) { | ||
return this.__data.getTimezones() | ||
} | ||
}, | ||
/** | ||
* sets timezone | ||
* @param {String} timezone - see `moment-timezone` | ||
* if `timezone` is `undefined` then all dates are considered local dates | ||
*/ | ||
setTimezone (timezone) { | ||
this.__timezone = timezone | ||
}, | ||
/** | ||
* get languages for selected country, state, region | ||
* @return {Array} containing ISO 639-1 language shortcodes | ||
*/ | ||
getLanguages () { | ||
return this.__languages | ||
}, | ||
/** | ||
* set language(s) for holiday names | ||
* @param {Array|String} language | ||
* @return {Array} set languages | ||
*/ | ||
setLanguages (language) { | ||
if (typeof language === 'string') { | ||
language = [ language ] | ||
} | ||
var tmp = {} | ||
this.__languages = [].concat( | ||
language, | ||
'en', | ||
(this.__conf ? this.__data.getLanguages() : []) | ||
).filter(function (l) { // filter out duplicates | ||
if (!l || tmp[l]) { | ||
return false | ||
} | ||
tmp[l] = 1 | ||
return true | ||
}) | ||
}, | ||
/** | ||
* get default day off as weekday | ||
* @return {String} weekday of day off | ||
*/ | ||
getDayOff () { | ||
if (this.__conf) { | ||
return this.__data.getDayOff() | ||
} | ||
}, | ||
/** | ||
* @private | ||
* @param {Number} year | ||
* @param {String} rule | ||
*/ | ||
_dateByRule (year, rule) { | ||
var _rule = this.holidays[rule] | ||
var dates = _rule.fn.inYear(year).get(this.__timezone) | ||
dates = dates.map((date) => { | ||
var odate = _.merge({}, | ||
_.omit(date, ['substitute']), | ||
_.omit(_rule, ['fn', 'enable', 'disable', 'substitute', 'active']) | ||
) | ||
if (_rule.substitute && date.substitute) { | ||
odate.substitute = true | ||
} | ||
return odate | ||
}) | ||
return dates | ||
}, | ||
/** | ||
* translate holiday object `o` to a language | ||
* @private | ||
* @param {Object} o | ||
* @param {Array} langs - languages for translation | ||
* @return {Object} translated holiday object | ||
*/ | ||
_translate (o, langs) { | ||
if (o && typeof o.name === 'object') { | ||
langs = langs || this.getLanguages() | ||
var name | ||
var subst | ||
for (var i in langs) { | ||
if ((name = o.name[langs[i]])) { | ||
o.name = name | ||
break | ||
} | ||
} | ||
if (o.substitute) { | ||
for (i in langs) { | ||
subst = this.__data.getSubstitueNames() | ||
if ((name = subst[langs[i]])) { | ||
o.name += ' (' + name + ')' | ||
break | ||
} | ||
} | ||
} | ||
} | ||
return o | ||
}, | ||
/** | ||
* set holiday types | ||
* @private | ||
* @param {Array} [t] - holiday types | ||
* @return {Object} new array of types | ||
*/ | ||
_setTypes (t) { | ||
t = t || [] | ||
var types = {} | ||
TYPES.map(function (type) { | ||
for (var i in t) { | ||
if (type !== t[i]) { | ||
return | ||
} | ||
} | ||
types[type] = 1 | ||
}) | ||
this.__types = types | ||
}, | ||
/** | ||
* check for supported holiday type | ||
* @private | ||
* @param {String} type | ||
* @return {Boolean} | ||
*/ | ||
_hasType (type) { | ||
return !!this.__types[type] | ||
} | ||
} | ||
module.exports = Holidays |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5
617
797305
149291
268
14984
+ Addeddate-holidays-parser@^1.2.0
+ Addedlodash.pick@^4.4.0
+ Addeddate-bengali-revised@1.0.2(transitive)
+ Addeddate-holidays-parser@1.6.0(transitive)
+ Addeddeepmerge@4.3.1(transitive)
+ Addedlodash.pick@4.4.0(transitive)
- Removedastronomia@^1.3.5
- Removedbabelify@^8.0.0
- Removedcaldate@^1.0.0
- Removeddate-chinese@^1.0.2
- Removeddate-easter@^0.2.2
- Removedlodash.get@^4.4.2
- Removedlodash.merge@^4.6.0
- Removedlodash.set@^4.3.2
- Removedmoment-timezone@^0.5.13
- Removed@ampproject/remapping@2.3.0(transitive)
- Removed@babel/code-frame@7.26.2(transitive)
- Removed@babel/compat-data@7.26.2(transitive)
- Removed@babel/core@7.26.0(transitive)
- Removed@babel/generator@7.26.2(transitive)
- Removed@babel/helper-compilation-targets@7.25.9(transitive)
- Removed@babel/helper-module-imports@7.25.9(transitive)
- Removed@babel/helper-module-transforms@7.26.0(transitive)
- Removed@babel/helper-string-parser@7.25.9(transitive)
- Removed@babel/helper-validator-identifier@7.25.9(transitive)
- Removed@babel/helper-validator-option@7.25.9(transitive)
- Removed@babel/helpers@7.26.0(transitive)
- Removed@babel/parser@7.26.2(transitive)
- Removed@babel/template@7.25.9(transitive)
- Removed@babel/traverse@7.25.9(transitive)
- Removed@babel/types@7.26.0(transitive)
- Removed@jridgewell/gen-mapping@0.3.5(transitive)
- Removed@jridgewell/resolve-uri@3.1.2(transitive)
- Removed@jridgewell/set-array@1.2.1(transitive)
- Removed@jridgewell/sourcemap-codec@1.5.0(transitive)
- Removed@jridgewell/trace-mapping@0.3.25(transitive)
- Removedastronomia@1.4.0(transitive)
- Removedbabel-core@7.0.0-bridge.0(transitive)
- Removedbabelify@8.0.0(transitive)
- Removedbrowserslist@4.24.2(transitive)
- Removedcaniuse-lite@1.0.30001680(transitive)
- Removedconvert-source-map@2.0.0(transitive)
- Removeddebug@4.3.7(transitive)
- Removedelectron-to-chromium@1.5.62(transitive)
- Removedescalade@3.2.0(transitive)
- Removedgensync@1.0.0-beta.2(transitive)
- Removedglobals@11.12.0(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedjsesc@3.0.2(transitive)
- Removedjson5@2.2.3(transitive)
- Removedlodash.get@4.4.2(transitive)
- Removedlodash.merge@4.6.2(transitive)
- Removedlodash.set@4.3.2(transitive)
- Removedlru-cache@5.1.1(transitive)
- Removedms@2.1.3(transitive)
- Removednode-releases@2.0.18(transitive)
- Removedpicocolors@1.1.1(transitive)
- Removedsemver@6.3.1(transitive)
- Removedupdate-browserslist-db@1.1.1(transitive)
- Removedyallist@3.1.1(transitive)
Updatedjs-yaml@^3.10.0