UNPKG

@guardian/threads

Version:
120 lines 3.95 kB
// Firefox and Chrome have different `Date.parse` functions so here we are // The idea of this is to have a best effort at human readalbe date parsing // I coulnd't really find a library that worked well in both Firefox and Chrome // A lot of libraries fall back to Date.parse which is great in Chrome, but pretty janky in Firefox - but necessary // That being said we don't want or need an extremely thorough range of formats, just basic day month year // 2019 // Feb 2019 // 10 Feb 2019 // 10th Feb 2018 var separators = '(?: +|_|-|/)'; var optionalOrdinalIndicators = '(?:st|nd|rd|th)?'; var monthYearDateRegex = new RegExp('^(\\d+|\\w+)' + separators + '(\\d+)$'); var dayMonthYearDateRegex = new RegExp('^(\\d+)' + optionalOrdinalIndicators + separators + '(\\d+|\\w+)' + separators + '(\\d+)$'); var monthNames = [ ['jan', 'january'], ['feb', 'february'], ['mar', 'march'], ['apr', 'april'], ['may'], ['jun', 'june'], ['jul', 'july'], ['aug', 'august'], ['sep', 'sept', 'september'], ['oct', 'october'], ['nov', 'november'], ['dec', 'december'], ]; export function parseDate(text, mode) { var trimmed = text.trim(); try { var p = parseDateNoFallback(trimmed, mode); if (!p) { return Date.parse(trimmed); } else { return p; } } catch (_) { // Fallback to native - hope they're in Chrome lol. // This *WILL NOT* respect the before/after flag so can lead to slightly unexpected results return Date.parse(trimmed); } } // Date parser mode will chose either the from start of your date or the end // This is because if you say, "Give me all documents from after 2018" you don't want the // calculation to be from the first of January because you'd get results from all of 2018 // // For example from_start '2018' returns 2018-01-01T00:00:00, from_end returns 2018-12-31T24:00:00 export function parseDateNoFallback(text, mode) { var year, month, day; // Check if we can just parse the text text as a single year year = Number(text); if (!isNaN(year)) { // Check if we can just parse the text text as a single year if (mode === 'from_end') { year += 1; } return Date.UTC(year, 0); } var monthYear = monthYearDateRegex.exec(text); if (monthYear !== null && monthYear.length === 3 && validateMonth(monthYear[1]) && validateYear(monthYear[2])) { year = Number(monthYear[2]); month = getMonthIndex(monthYear[1]); if (mode === 'from_end') { month += 1; return Date.UTC(year, month); } else { return Date.UTC(year, month); } } var dayMonthYear = dayMonthYearDateRegex.exec(text); if (dayMonthYear !== null && dayMonthYear.length === 4 && validateDay(dayMonthYear[1]) && validateMonth(dayMonthYear[2]) && validateYear(dayMonthYear[3])) { year = Number(dayMonthYear[3]); month = getMonthIndex(dayMonthYear[2]); day = Number(dayMonthYear[1]); if (mode === 'from_end') { day += 1; return Date.UTC(year, month, day); } else { return Date.UTC(year, month, day); } } return null; } function validateDay(day) { var num = Number(day); return !!num; } function validateMonth(month) { var num = Number(month); return (!!num || monthNames.some(function (monthTexts) { return monthTexts.includes(month.toLowerCase()); })); } function getMonthIndex(month) { var num = Number(month); if (num) { return num - 1; } return monthNames.findIndex(function (names) { return names.includes(month.toLowerCase()); }); } function validateYear(year) { var num = Number(year); return !!num; } //# sourceMappingURL=parseDate.js.map