UNPKG

half-past

Version:

natural-language date-parsing in javascript

301 lines (282 loc) 10.5 kB
'use strict'; const spacetime = require('spacetime'); const Day = require('../units/Day') //we try to support a bunch of these, but are going to miss some. PRs welcome //yep, let jan = 0; let feb = 1; let march = 2; let april = 3; let may = 4; let june = 5; let july = 6; let august = 7; let sep = 8; let oct = 9; let nov = 10; let dec = 11; let fixed_holidays = { 'new years eve': [dec, 31], 'new years': [jan, 1], 'new years day': [jan, 1], 'inauguration day': [jan, 20], 'australia day': [jan, 26], 'national freedom day': [feb, 1], 'groundhog day': [feb, 2], 'rosa parks day': [feb, 4], 'valentines day': [feb, 14], 'saint valentines day': [feb, 14], 'st valentines day ': [feb, 14], 'saint patricks day': [march, 17], 'st patricks day': [march, 17], 'april fools': [april, 1], 'april fools day': [april, 1], 'emancipation day': [april, 16], 'labour day': [may, 1], 'cinco de mayo': [may, 5], 'national nurses day': [may, 6], 'harvey milk day': [may, 22], 'victoria day': [may, 24], 'juneteenth': [june, 19], 'canada day': [july, 1], 'independence day': [july, 4], 'independents day': [july, 4], 'bastille day': [july, 14], 'purple heart day': [august, 7], 'womens equality day': [august, 26], '16 de septiembre': [sep, 16], 'dieciseis de septiembre': [sep, 16], 'grito de dolores': [sep, 16], 'halloween': [oct, 31], 'all hallows eve': [oct, 31], 'day of the dead': [oct, 31], // Ranged holiday [nov, 2], 'dia de muertos': [oct, 31], // Ranged holiday [nov, 2], 'veterans day': [nov, 11], 'st andrews day': [nov, 30], 'saint andrews day': [nov, 30], 'all saints day': [nov, 1], 'all sts day': [nov, 1], 'armistice day': [nov, 11], 'rememberance day': [nov, 11], 'christmas eve': [dec, 24], 'christmas': [dec, 25], 'xmas': [dec, 25], 'boxing day': [dec, 26], 'st stephens day': [dec, 26], 'saint stephens day': [dec, 26], // Fixed religious and cultural holidays // Catholic + Christian 'epiphany': [jan, 6], 'orthodox christmas day': [jan, 7], 'orthodox new year': [jan, 14], 'assumption of mary': [august, 15], 'all souls day': [nov, 2], 'feast of the immaculate conception': [dec, 8], 'feast of our lady of guadalupe': [dec, 12], // Kwanzaa 'kwanzaa': [dec, 26], // Ranged holiday [jan, 1], // Pagan / metal 🤘 'imbolc': [feb, 2], 'beltaine': [may, 1], 'lughnassadh': [august, 1], 'samhain': [oct, 31] }; // hardcoded dates for astronomical holidays // ----please change, every few years(!)--- const moving_holidays = { 2017: { // Astronomical major holidays 'martin luther king': [jan, 16], //[third monday in january], 'mlk': [jan, 16], //[third Monday in January], 'presidents day': [feb, 20], //[third monday in february], 'mardi gras': [feb, 28], //[47 days before easter], 'commonwealth day': [march, 13], //[second monday in march], 'tax day': [april, 18], 'memorial day': [may, 29], //[last monday in may], 'mothers day': [may, 14], //[second Sunday in May], 'fathers day': [june, 18], //[third Sunday in June], 'labor day': [sep, 4], //[first monday in september], 'columbus day': [oct, 9], //[second monday in october], 'indigenous peoples day': [oct, 9], //[second monday in October], 'canadian thanksgiving': [oct, 9], //[second monday in october], 'election day': [nov, 7], // [Tuesday following the first Monday in November], 'thanksgiving': [nov, 23], //[fourth Thursday in November], 't-day': [nov, 23], //[fourth Thursday in November], 'turkey day': [nov, 23], //[fourth Thursday in November], 'black friday': [nov, 24], //[fourth tuesday in november], 'cyber monday': [nov, 27], // Astronomical religious and cultural holidays // Catholic + Christian 'ash wednesday': [march, 1], // [First day of Lent], 'palm sunday': [april, 9], // [Sunday before Easter Sunday], 'maundy thursday': [april, 13], // [The day before Good Friday], 'good friday': [april, 14], 'holy saturday': [april, 15], 'easter': [april, 16], 'easter sunday': [april, 16], 'easter monday': [april, 17], 'orthodox good friday': [april, 14], 'orthodox holy saturday': [april, 15], 'orthodox easter': [april, 16], 'orthodox easter monday': [april, 17], 'ascension day': [may, 25], 'pentecost': [june, 4], 'whitsunday': [june, 4], 'whit sunday': [june, 4], 'whit monday': [june, 5], // [The day after Pentecost], 'trinity sunday': [june, 11], // [The Sunday after Pentecost], 'corpus christi': [june, 15], 'advent': [dec, 3], // Ranged holiday [dec, 25] [The Sunday nearest St Andrew’s Day, encompassing the next three Sundays, ending on Christmas Day], // Jewish 'tu bishvat': [feb, 11], 'tu bshevat': [feb, 11], 'purim': [march, 12], 'passover': [april, 11], // Ranged holiday [april, 18], 'yom hashoah': [april, 24], 'lag baomer': [may, 14], 'shavuot': [may, 31], 'tisha bav': [august, 1], 'rosh hashana': [sep, 21], 'yom kippur': [sep, 30], 'sukkot': [oct, 5], // Ranged holiday [oct, 11], 'shmini atzeret': [oct, 12], 'simchat torah': [oct, 13], 'chanukah': [dec, 13], // Ranged holiday [dec, 20], 'hanukkah': [dec, 13], // Ranged holiday [dec, 20], // Muslim 'isra and miraj': [april, 24], 'lailat al-qadr': [june, 21], 'eid al-fitr': [june, 26], 'id al-Fitr': [june, 26], 'eid ul-Fitr': [june, 26], 'ramadan': [may, 27], // Ranged holiday [, ], 'eid al-adha': [sep, 2], 'muharram': [sep, 22], 'the prophets birthday': [dec, 1], // Pagan / metal 🤘 'ostara': [march, 20], 'march equinox': [march, 20], 'vernal equinox': [march, 20], 'litha': [june, 21], 'june solistice': [june, 21], 'summer solistice': [june, 21], 'mabon': [sep, 22], 'september equinox': [sep, 22], 'autumnal equinox': [sep, 22], 'yule': [dec, 21], 'december solstice': [dec, 21], 'winter solstice': [dec, 21], // Additional important holidays 'chinese new year': [jan, 28], 'diwali': [oct, 19] }, 2018: { // Astronomical major holidays 'martin luther king': [jan, 15], //[third monday in january], 'mlk': [jan, 15], //[third Monday in January], 'presidents day': [feb, 19], //[third monday in february], 'mardi gras': [feb, 13], //[47 days before easter], 'commonwealth day': [march, 12], //[second monday in march], 'tax day': [april, 17], 'mothers day': [may, 13], //[second Sunday in May], 'memorial day': [may, 28], //[last monday in may], 'fathers day': [june, 17], //[third Sunday in June], 'labor day': [sep, 3], //[first monday in september], 'columbus day': [oct, 8], //[second monday in october], 'indigenous peoples day': [oct, 8], //[second monday in October], 'canadian thanksgiving': [oct, 8], //[second monday in october], 'election day': [nov, 6], // [Tuesday following the first Monday in November], 'thanksgiving': [nov, 22], // [fourth Thursday in November], 't-day': [nov, 22], // [fourth Thursday in November], 'turkey day': [nov, 22], //[fourth Thursday in November], 'black friday': [nov, 23], //[fourth tuesday in november], 'cyber monday': [nov, 26], // Astronomical religious and cultural holidays // Catholic + Christian 'ash wednesday': [feb, 14], // [First day of Lent], 'palm sunday': [march, 25], // [Sunday before Easter Sunday], 'maundy thursday': [march, 29], // [The day before Good Friday], 'good friday': [march, 30], 'holy saturday': [march, 31], 'easter': [april, 1], 'easter sunday': [april, 1], 'easter monday': [april, 2], 'orthodox good friday': [april, 6], 'orthodox holy saturday': [april, 7], 'orthodox easter': [april, 8], 'orthodox easter monday': [april, 9], 'ascension day': [may, 10], 'pentecost': [may, 20], 'whitsunday': [may, 20], 'whit sunday': [may, 20], 'whit monday': [may, 21], // [The day after Pentecost], 'trinity sunday': [may, 27], // [The Sunday after Pentecost], 'corpus christi': [may, 31], 'advent': [dec, 2], // Ranged holiday [dec, 25] [The Sunday nearest St Andrew’s Day, encompassing the next three Sundays, ending on Christmas Day], // Jewish 'tu bishvat': [jan, 31], 'tu bshevat': [jan, 31], 'purim': [march, 1], 'passover': [march, 31], // Ranged holiday [april, 7], 'yom hashoah': [april, 11], 'lag baomer': [may, 3], 'shavuot': [may, 20], 'tisha bav': [july, 22], 'rosh hashana': [sep, 10], 'yom kippur': [sep, 19], 'sukkot': [sep, 24], // Ranged holiday [sep, 30], 'shmini atzeret': [oct, 1], 'simchat torah': [oct, 2], 'chanukah': [dec, 3], // Ranged holiday [dec, 30], 'hanukkah': [dec, 3], // Ranged holiday [dec, 30], // Muslim 'isra and miraj': [april, 13], 'lailat al-qadr': [june, 10], 'eid al-fitr': [june, 15], 'id al-Fitr': [june, 15], 'eid ul-Fitr': [june, 15], 'ramadan': [may, 16], // Ranged holiday [, ], 'eid al-adha': [sep, 22], 'muharram': [sep, 12], 'the prophets birthday': [nov, 21], // Pagan / metal 'ostara': [march, 20], 'march equinox': [march, 20], 'vernal equinox': [march, 20], 'litha': [june, 21], 'june solistice': [june, 21], 'summer solistice': [june, 21], 'mabon': [sep, 23], 'september equinox': [sep, 23], 'autumnal equinox': [sep, 23], 'yule': [dec, 21], 'december solstice': [dec, 21], 'winter solstice': [dec, 21], // Additional important holidays 'chinese new year': [feb, 16], 'diwali': [nov, 7] } }; const holidayParser = (ts, context) => { // let today = spacetime(context.now) let year = today.year(); //spin-out the holidays for this year let holidays = Object.assign({}, fixed_holidays, moving_holidays[year] || {}); //try them all! (may be slow) let keys = Object.keys(holidays); for (let i = 0; i < keys.length; i++) { let m = ts.match(keys[i]); if (m.found) { let holiday = holidays[keys[i]]; let d = spacetime([year, holiday[0], holiday[1]], context.timezone); //default next year, if it's already happened if (d.isAfter(today)) { d.add(1, 'year'); } let iso = d.format('iso-short') return new Day(iso, context) } } return null; }; module.exports = holidayParser;