chrono-node
Advanced tools
Comparing version 2.1.5 to 2.1.6
@@ -32,4 +32,5 @@ import { DebugHandler, DebugConsume } from "./debugging"; | ||
} | ||
export * as de from "./locales/de"; | ||
export * as en from "./locales/en"; | ||
export * as fr from "./locales/fr"; | ||
export * as ja from "./locales/ja"; |
@@ -41,4 +41,5 @@ "use strict"; | ||
})(Meridiem = exports.Meridiem || (exports.Meridiem = {})); | ||
exports.de = __importStar(require("./locales/de")); | ||
exports.en = __importStar(require("./locales/en")); | ||
exports.fr = __importStar(require("./locales/fr")); | ||
exports.ja = __importStar(require("./locales/ja")); |
import { OpUnitType } from "dayjs"; | ||
import { TimeUnits } from "../../utils/timeunits"; | ||
export declare const WEEKDAY_DICTIONARY: { | ||
@@ -24,4 +25,2 @@ [word: string]: number; | ||
export declare const TIME_UNITS_PATTERN: string; | ||
export declare function parseTimeUnits(timeunitText: any): { | ||
[c in OpUnitType]?: number; | ||
}; | ||
export declare function parseTimeUnits(timeunitText: any): TimeUnits; |
@@ -124,3 +124,3 @@ "use strict"; | ||
"twenty-ninth": 29, | ||
thirtieth: 30, | ||
"thirtieth": 30, | ||
"thirty first": 31, | ||
@@ -148,2 +148,3 @@ "thirty-first": 31, | ||
months: "month", | ||
y: "year", | ||
yr: "year", | ||
@@ -153,3 +154,3 @@ year: "year", | ||
}; | ||
exports.NUMBER_PATTERN = `(?:${pattern_1.matchAnyPattern(exports.INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?(?:\\s*few)?|few)`; | ||
exports.NUMBER_PATTERN = `(?:${pattern_1.matchAnyPattern(exports.INTEGER_WORD_DICTIONARY)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?(?:\\s*few)?|few|several|a?\\s*couple\\s*(?:of)?)`; | ||
function parseNumberPattern(match) { | ||
@@ -169,2 +170,8 @@ const num = match.toLowerCase(); | ||
} | ||
else if (num.match(/couple/)) { | ||
return 2; | ||
} | ||
else if (num.match(/several/)) { | ||
return 7; | ||
} | ||
return parseFloat(num); | ||
@@ -204,3 +211,4 @@ } | ||
const SINGLE_TIME_UNIT_PATTERN_NO_CAPTURE = SINGLE_TIME_UNIT_PATTERN.replace(/\((?!\?)/g, "(?:"); | ||
exports.TIME_UNITS_PATTERN = `(?:${SINGLE_TIME_UNIT_PATTERN_NO_CAPTURE})+`; | ||
exports.TIME_UNITS_PATTERN = `(?:(?:about|around)\\s*)?` + | ||
`${SINGLE_TIME_UNIT_PATTERN_NO_CAPTURE}\\s*(?:,?\\s*${SINGLE_TIME_UNIT_PATTERN_NO_CAPTURE})*`; | ||
function parseTimeUnits(timeunitText) { | ||
@@ -207,0 +215,0 @@ const fragments = {}; |
@@ -7,3 +7,3 @@ "use strict"; | ||
exports.createConfiguration = exports.createCasualConfiguration = exports.parseDate = exports.parse = exports.GB = exports.strict = exports.casual = void 0; | ||
const ENTimeUnitDeadlineFormatParser_1 = __importDefault(require("./parsers/ENTimeUnitDeadlineFormatParser")); | ||
const ENTimeUnitWithinFormatParser_1 = __importDefault(require("./parsers/ENTimeUnitWithinFormatParser")); | ||
const ENMonthNameLittleEndianParser_1 = __importDefault(require("./parsers/ENMonthNameLittleEndianParser")); | ||
@@ -26,2 +26,3 @@ const ENMonthNameMiddleEndianParser_1 = __importDefault(require("./parsers/ENMonthNameMiddleEndianParser")); | ||
const SlashDateFormatParser_1 = __importDefault(require("../../common/parsers/SlashDateFormatParser")); | ||
const ENTimeUnitCasualRelativeFormatParser_1 = __importDefault(require("./parsers/ENTimeUnitCasualRelativeFormatParser")); | ||
exports.casual = new chrono_1.Chrono(createCasualConfiguration(false)); | ||
@@ -44,2 +45,3 @@ exports.strict = new chrono_1.Chrono(createConfiguration(true, false)); | ||
option.parsers.unshift(new ENRelativeDateFormatParser_1.default()); | ||
option.parsers.unshift(new ENTimeUnitCasualRelativeFormatParser_1.default()); | ||
return option; | ||
@@ -52,3 +54,3 @@ } | ||
new SlashDateFormatParser_1.default(littleEndian), | ||
new ENTimeUnitDeadlineFormatParser_1.default(strictMode), | ||
new ENTimeUnitWithinFormatParser_1.default(), | ||
new ENMonthNameLittleEndianParser_1.default(), | ||
@@ -55,0 +57,0 @@ new ENMonthNameMiddleEndianParser_1.default(), |
@@ -12,3 +12,3 @@ "use strict"; | ||
innerPattern(context) { | ||
return /(now|today|tonight|tomorrow|tmr|yesterday|last\s*night)(?=\W|$)/i; | ||
return /(now|today|tonight|midnight|tomorrow|tmr|yesterday|last\s*night)(?=\W|$)/i; | ||
} | ||
@@ -38,14 +38,10 @@ innerExtract(context, match) { | ||
case "tmr": | ||
if (targetDate.hour() > 1) { | ||
targetDate = targetDate.add(1, "day"); | ||
dayjs_2.assignSimilarDate(component, targetDate); | ||
dayjs_2.implySimilarTime(component, targetDate); | ||
} | ||
else { | ||
dayjs_2.assignSimilarDate(component, targetDate); | ||
component.imply("hour", 12); | ||
component.imply("minute", 0); | ||
component.imply("second", 0); | ||
} | ||
dayjs_2.assignTheNextDay(component, targetDate); | ||
break; | ||
case "midnight": | ||
dayjs_2.assignTheNextDay(component, targetDate); | ||
component.imply("hour", 0); | ||
component.imply("minute", 0); | ||
component.imply("second", 0); | ||
break; | ||
case "yesterday": | ||
@@ -52,0 +48,0 @@ targetDate = targetDate.add(-1, "day"); |
@@ -7,5 +7,2 @@ import { ParsingContext } from "../../../chrono"; | ||
innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents; | ||
extractTimeReference(context: ParsingContext, timeUnitWord: string, num: number): ParsingComponents; | ||
extractDateReference(context: ParsingContext, dateUnitWord: string, num: number): ParsingComponents; | ||
extractThisReference(context: ParsingContext, relativeWord: string): ParsingComponents; | ||
} |
@@ -7,11 +7,9 @@ "use strict"; | ||
const constants_1 = require("../constants"); | ||
const results_1 = require("../../../results"); | ||
const dayjs_1 = __importDefault(require("dayjs")); | ||
const AbstractParserWithWordBoundary_1 = require("../../../common/parsers/AbstractParserWithWordBoundary"); | ||
const PATTERN = new RegExp("(this|next|last|past)\\s*" + | ||
`(${constants_1.NUMBER_PATTERN})?\\s*` + | ||
"(seconds?|min(?:ute)?s?|hours?|days?|weeks?|months?|years?)(?=\\s*)" + | ||
"(?=\\W|$)", "i"); | ||
const pattern_1 = require("../../../utils/pattern"); | ||
const PATTERN = new RegExp(`(this|next|last|past)\\s*(${pattern_1.matchAnyPattern(constants_1.TIME_UNIT_DICTIONARY)})(?=\\s*)` + "(?=\\W|$)", "i"); | ||
const MODIFIER_WORD_GROUP = 1; | ||
const MULTIPLIER_WORD_GROUP = 2; | ||
const RELATIVE_WORD_GROUP = 3; | ||
const RELATIVE_WORD_GROUP = 2; | ||
class ENRelativeDateFormatParser extends AbstractParserWithWordBoundary_1.AbstractParserWithWordBoundaryChecking { | ||
@@ -22,75 +20,18 @@ innerPattern() { | ||
innerExtract(context, match) { | ||
if (match[MODIFIER_WORD_GROUP].toLowerCase().match(/^this/)) { | ||
if (match[MULTIPLIER_WORD_GROUP]) { | ||
return null; | ||
} | ||
return this.extractThisReference(context, match[RELATIVE_WORD_GROUP]); | ||
} | ||
const modifier = match[MODIFIER_WORD_GROUP].toLowerCase().match(/^next/) ? 1 : -1; | ||
const parsedNum = match[MULTIPLIER_WORD_GROUP] ? constants_1.parseNumberPattern(match[MULTIPLIER_WORD_GROUP]) : 1; | ||
const modifier = match[MODIFIER_WORD_GROUP].toLowerCase(); | ||
const unitWord = match[RELATIVE_WORD_GROUP].toLowerCase(); | ||
if (unitWord.match(/day|week|month|year/i)) { | ||
return this.extractDateReference(context, unitWord, parsedNum * modifier); | ||
const timeunit = constants_1.TIME_UNIT_DICTIONARY[unitWord]; | ||
if (modifier == "next") { | ||
const timeUnits = {}; | ||
timeUnits[timeunit] = 1; | ||
return results_1.ParsingComponents.createRelativeFromRefDate(context.refDate, timeUnits); | ||
} | ||
else { | ||
return this.extractTimeReference(context, unitWord, parsedNum * modifier); | ||
if (modifier == "last" || modifier == "past") { | ||
const timeUnits = {}; | ||
timeUnits[timeunit] = -1; | ||
return results_1.ParsingComponents.createRelativeFromRefDate(context.refDate, timeUnits); | ||
} | ||
} | ||
extractTimeReference(context, timeUnitWord, num) { | ||
const components = context.createParsingComponents(); | ||
let date = dayjs_1.default(context.refDate); | ||
if (timeUnitWord.match(/hour/i)) { | ||
date = date.add(num, "hour"); | ||
components.imply("minute", date.minute()); | ||
components.imply("second", date.second()); | ||
} | ||
else if (timeUnitWord.match(/min/i)) { | ||
date = date.add(num, "minute"); | ||
components.assign("minute", date.minute()); | ||
components.imply("second", date.second()); | ||
} | ||
else if (timeUnitWord.match(/second/i)) { | ||
date = date.add(num, "second"); | ||
components.assign("second", date.second()); | ||
components.assign("minute", date.minute()); | ||
} | ||
components.assign("hour", date.hour()); | ||
components.assign("year", date.year()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("day", date.date()); | ||
return components; | ||
} | ||
extractDateReference(context, dateUnitWord, num) { | ||
const components = context.createParsingComponents(); | ||
let date = dayjs_1.default(context.refDate); | ||
if (dateUnitWord.match(/day/i)) { | ||
date = date.add(num, "d"); | ||
components.assign("year", date.year()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("day", date.date()); | ||
} | ||
else if (dateUnitWord.match(/week/i)) { | ||
date = date.add(num * 7, "d"); | ||
components.imply("day", date.date()); | ||
components.imply("month", date.month() + 1); | ||
components.imply("year", date.year()); | ||
} | ||
else if (dateUnitWord.match(/month/i)) { | ||
date = date.add(num, "month"); | ||
components.imply("day", date.date()); | ||
components.assign("year", date.year()); | ||
components.assign("month", date.month() + 1); | ||
} | ||
else if (dateUnitWord.match(/year/i)) { | ||
date = date.add(num, "year"); | ||
components.imply("day", date.date()); | ||
components.imply("month", date.month() + 1); | ||
components.assign("year", date.year()); | ||
} | ||
return components; | ||
} | ||
extractThisReference(context, relativeWord) { | ||
const components = context.createParsingComponents(); | ||
let date = dayjs_1.default(context.refDate); | ||
if (relativeWord.match(/week/i)) { | ||
if (unitWord.match(/week/i)) { | ||
date = date.add(-date.get("d"), "d"); | ||
@@ -101,3 +42,3 @@ components.imply("day", date.date()); | ||
} | ||
else if (relativeWord.match(/month/i)) { | ||
else if (unitWord.match(/month/i)) { | ||
date = date.add(-date.date() + 1, "d"); | ||
@@ -108,3 +49,3 @@ components.imply("day", date.date()); | ||
} | ||
else if (relativeWord.match(/year/i)) { | ||
else if (unitWord.match(/year/i)) { | ||
date = date.add(-date.date() + 1, "d"); | ||
@@ -111,0 +52,0 @@ date = date.add(-date.month(), "month"); |
@@ -20,19 +20,22 @@ "use strict"; | ||
const hour = components.get("hour"); | ||
if (hour > 6 && hour < 12) { | ||
if (hour >= 6 && hour < 12) { | ||
components.assign("hour", components.get("hour") + 12); | ||
components.assign("meridiem", index_1.Meridiem.PM); | ||
} | ||
else if (hour < 6) { | ||
components.assign("meridiem", index_1.Meridiem.AM); | ||
} | ||
} | ||
if (match[0].endsWith("afternoon")) { | ||
components.assign("meridiem", index_1.Meridiem.PM); | ||
const hour = components.get("hour"); | ||
if (hour >= 0 && hour <= 6) { | ||
components.assign("hour", components.get("hour") + 12); | ||
components.assign("meridiem", index_1.Meridiem.PM); | ||
} | ||
} | ||
if (match[0].endsWith("morning")) { | ||
components.assign("meridiem", index_1.Meridiem.AM); | ||
const hour = components.get("hour"); | ||
if (hour < 12) { | ||
components.assign("hour", components.get("hour")); | ||
components.assign("meridiem", index_1.Meridiem.AM); | ||
} | ||
@@ -39,0 +42,0 @@ } |
@@ -6,2 +6,3 @@ "use strict"; | ||
const AbstractParserWithWordBoundary_1 = require("../../../common/parsers/AbstractParserWithWordBoundary"); | ||
const timeunits_1 = require("../../../utils/timeunits"); | ||
const PATTERN = new RegExp("" + "(" + constants_1.TIME_UNITS_PATTERN + ")" + "(?:ago|before|earlier)(?=(?:\\W|$))", "i"); | ||
@@ -18,9 +19,7 @@ const STRICT_PATTERN = new RegExp("" + "(" + constants_1.TIME_UNITS_PATTERN + ")" + "ago(?=(?:\\W|$))", "i"); | ||
innerExtract(context, match) { | ||
const fragments = constants_1.parseTimeUnits(match[1]); | ||
for (const key in fragments) { | ||
fragments[key] = -fragments[key]; | ||
} | ||
return results_1.ParsingComponents.createRelativeFromRefDate(context.refDate, fragments); | ||
const timeUnits = constants_1.parseTimeUnits(match[1]); | ||
const outputTimeUnits = timeunits_1.reverseTimeUnits(timeUnits); | ||
return results_1.ParsingComponents.createRelativeFromRefDate(context.refDate, outputTimeUnits); | ||
} | ||
} | ||
exports.default = ENTimeUnitAgoFormatParser; |
@@ -8,3 +8,2 @@ "use strict"; | ||
const STRICT_PATTERN = new RegExp("" + "(" + constants_1.TIME_UNITS_PATTERN + ")" + "(later|from now)" + "(?=(?:\\W|$))", "i"); | ||
const GROUP_NUM_SUFFIX = 2; | ||
const GROUP_NUM_TIMEUNITS = 1; | ||
@@ -20,6 +19,2 @@ class ENTimeUnitLaterFormatParser extends AbstractParserWithWordBoundary_1.AbstractParserWithWordBoundaryChecking { | ||
innerExtract(context, match) { | ||
const suffix = match[GROUP_NUM_SUFFIX].toLowerCase().trim(); | ||
if (!suffix) { | ||
return null; | ||
} | ||
const fragments = constants_1.parseTimeUnits(match[GROUP_NUM_TIMEUNITS]); | ||
@@ -26,0 +21,0 @@ return results_1.ParsingComponents.createRelativeFromRefDate(context.refDate, fragments); |
@@ -24,5 +24,2 @@ "use strict"; | ||
const offset = constants_1.WEEKDAY_DICTIONARY[dayOfWeek]; | ||
if (offset === undefined) { | ||
return null; | ||
} | ||
const prefix = match[PREFIX_GROUP]; | ||
@@ -29,0 +26,0 @@ const postfix = match[POSTFIX_GROUP]; |
@@ -9,3 +9,3 @@ import { Component, ParsedComponents, ParsedResult } from "./index"; | ||
}); | ||
get(component: Component): number | undefined; | ||
get(component: Component): number | null; | ||
date(): Date; | ||
@@ -12,0 +12,0 @@ isCertain(component: Component): boolean; |
@@ -33,3 +33,3 @@ "use strict"; | ||
} | ||
return undefined; | ||
return null; | ||
} | ||
@@ -113,3 +113,3 @@ date() { | ||
const currentTimezoneOffset = result.utcOffset(); | ||
const targetTimezoneOffset = this.get("timezoneOffset") !== undefined ? this.get("timezoneOffset") : currentTimezoneOffset; | ||
const targetTimezoneOffset = this.get("timezoneOffset") !== null ? this.get("timezoneOffset") : currentTimezoneOffset; | ||
const adjustTimezoneOffset = targetTimezoneOffset - currentTimezoneOffset; | ||
@@ -132,2 +132,5 @@ result = result.add(-adjustTimezoneOffset, "minute"); | ||
components.assign("second", date.second()); | ||
components.assign("day", date.date()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("year", date.year()); | ||
} | ||
@@ -138,15 +141,15 @@ else { | ||
components.imply("second", date.second()); | ||
} | ||
if (fragments["d"] || fragments["month"] || fragments["year"]) { | ||
components.assign("day", date.date()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("year", date.year()); | ||
} | ||
else { | ||
if (fragments["week"]) { | ||
components.imply("weekday", date.day()); | ||
if (fragments["d"]) { | ||
components.assign("day", date.date()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("year", date.year()); | ||
} | ||
components.imply("day", date.date()); | ||
components.imply("month", date.month() + 1); | ||
components.imply("year", date.year()); | ||
else { | ||
if (fragments["week"]) { | ||
components.imply("weekday", date.day()); | ||
} | ||
components.imply("day", date.date()); | ||
components.imply("month", date.month() + 1); | ||
components.imply("year", date.year()); | ||
} | ||
} | ||
@@ -153,0 +156,0 @@ return components; |
@@ -18,3 +18,3 @@ { | ||
"license": "MIT", | ||
"version": "2.1.5", | ||
"version": "2.1.6", | ||
"directories": { | ||
@@ -21,0 +21,0 @@ "source": "./src", |
@@ -57,4 +57,5 @@ import { DebugHandler, DebugConsume } from "./debugging"; | ||
// export * as xx from './locales/xx' | ||
export * as de from "./locales/de"; | ||
export * as en from "./locales/en"; | ||
export * as fr from "./locales/fr"; | ||
export * as ja from "./locales/ja"; |
import { OpUnitType } from "dayjs"; | ||
import { matchAnyPattern } from "../../utils/pattern"; | ||
import { findMostLikelyADYear } from "../../calculation/years"; | ||
import { TimeUnits } from "../../utils/timeunits"; | ||
@@ -126,3 +127,3 @@ export const WEEKDAY_DICTIONARY: { [word: string]: number } = { | ||
"twenty-ninth": 29, | ||
thirtieth: 30, | ||
"thirtieth": 30, | ||
"thirty first": 31, | ||
@@ -151,2 +152,3 @@ "thirty-first": 31, | ||
months: "month", | ||
y: "year", | ||
yr: "year", | ||
@@ -161,3 +163,3 @@ year: "year", | ||
INTEGER_WORD_DICTIONARY | ||
)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?(?:\\s*few)?|few)`; | ||
)}|[0-9]+|[0-9]+\\.[0-9]+|half(?:\\s*an?)?|an?(?:\\s*few)?|few|several|a?\\s*couple\\s*(?:of)?)`; | ||
@@ -174,2 +176,6 @@ export function parseNumberPattern(match: string): number { | ||
return 0.5; | ||
} else if (num.match(/couple/)) { | ||
return 2; | ||
} else if (num.match(/several/)) { | ||
return 7; | ||
} | ||
@@ -225,5 +231,7 @@ | ||
export const TIME_UNITS_PATTERN = `(?:${SINGLE_TIME_UNIT_PATTERN_NO_CAPTURE})+`; | ||
export const TIME_UNITS_PATTERN = | ||
`(?:(?:about|around)\\s*)?` + | ||
`${SINGLE_TIME_UNIT_PATTERN_NO_CAPTURE}\\s*(?:,?\\s*${SINGLE_TIME_UNIT_PATTERN_NO_CAPTURE})*`; | ||
export function parseTimeUnits(timeunitText): { [c in OpUnitType]?: number } { | ||
export function parseTimeUnits(timeunitText): TimeUnits { | ||
const fragments = {}; | ||
@@ -230,0 +238,0 @@ let remainingText = timeunitText; |
@@ -1,2 +0,2 @@ | ||
import ENTimeUnitDeadlineFormatParser from "./parsers/ENTimeUnitDeadlineFormatParser"; | ||
import ENTimeUnitWithinFormatParser from "./parsers/ENTimeUnitWithinFormatParser"; | ||
import ENMonthNameLittleEndianParser from "./parsers/ENMonthNameLittleEndianParser"; | ||
@@ -22,2 +22,3 @@ import ENMonthNameMiddleEndianParser from "./parsers/ENMonthNameMiddleEndianParser"; | ||
import SlashDateFormatParser from "../../common/parsers/SlashDateFormatParser"; | ||
import ENTimeUnitCasualRelativeFormatParser from "./parsers/ENTimeUnitCasualRelativeFormatParser"; | ||
@@ -44,2 +45,3 @@ // Shortcuts | ||
option.parsers.unshift(new ENRelativeDateFormatParser()); | ||
option.parsers.unshift(new ENTimeUnitCasualRelativeFormatParser()); | ||
return option; | ||
@@ -53,3 +55,3 @@ } | ||
new SlashDateFormatParser(littleEndian), | ||
new ENTimeUnitDeadlineFormatParser(strictMode), | ||
new ENTimeUnitWithinFormatParser(), | ||
new ENMonthNameLittleEndianParser(), | ||
@@ -56,0 +58,0 @@ new ENMonthNameMiddleEndianParser(), |
@@ -6,7 +6,7 @@ import { ParsingContext } from "../../../chrono"; | ||
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary"; | ||
import { assignSimilarDate, implySimilarTime } from "../../../utils/dayjs"; | ||
import { assignSimilarDate, assignTheNextDay, implySimilarTime } from "../../../utils/dayjs"; | ||
export default class ENCasualDateParser extends AbstractParserWithWordBoundaryChecking { | ||
innerPattern(context: ParsingContext): RegExp { | ||
return /(now|today|tonight|tomorrow|tmr|yesterday|last\s*night)(?=\W|$)/i; | ||
return /(now|today|tonight|midnight|tomorrow|tmr|yesterday|last\s*night)(?=\W|$)/i; | ||
} | ||
@@ -41,13 +41,11 @@ | ||
case "tmr": | ||
assignTheNextDay(component, targetDate); | ||
break; | ||
case "midnight": | ||
// Check not "Tomorrow" on late night | ||
if (targetDate.hour() > 1) { | ||
targetDate = targetDate.add(1, "day"); | ||
assignSimilarDate(component, targetDate); | ||
implySimilarTime(component, targetDate); | ||
} else { | ||
assignSimilarDate(component, targetDate); | ||
component.imply("hour", 12); | ||
component.imply("minute", 0); | ||
component.imply("second", 0); | ||
} | ||
assignTheNextDay(component, targetDate); | ||
component.imply("hour", 0); | ||
component.imply("minute", 0); | ||
component.imply("second", 0); | ||
break; | ||
@@ -54,0 +52,0 @@ |
@@ -1,12 +0,10 @@ | ||
import { NUMBER_PATTERN, parseNumberPattern } from "../constants"; | ||
import { Parser, ParsingContext } from "../../../chrono"; | ||
import { parseNumberPattern, TIME_UNIT_DICTIONARY } from "../constants"; | ||
import { ParsingContext } from "../../../chrono"; | ||
import { ParsingComponents } from "../../../results"; | ||
import dayjs from "dayjs"; | ||
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary"; | ||
import { matchAnyPattern } from "../../../utils/pattern"; | ||
const PATTERN = new RegExp( | ||
"(this|next|last|past)\\s*" + | ||
`(${NUMBER_PATTERN})?\\s*` + | ||
"(seconds?|min(?:ute)?s?|hours?|days?|weeks?|months?|years?)(?=\\s*)" + | ||
"(?=\\W|$)", | ||
`(this|next|last|past)\\s*(${matchAnyPattern(TIME_UNIT_DICTIONARY)})(?=\\s*)` + "(?=\\W|$)", | ||
"i" | ||
@@ -16,4 +14,3 @@ ); | ||
const MODIFIER_WORD_GROUP = 1; | ||
const MULTIPLIER_WORD_GROUP = 2; | ||
const RELATIVE_WORD_GROUP = 3; | ||
const RELATIVE_WORD_GROUP = 2; | ||
@@ -26,85 +23,23 @@ export default class ENRelativeDateFormatParser extends AbstractParserWithWordBoundaryChecking { | ||
innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents { | ||
if (match[MODIFIER_WORD_GROUP].toLowerCase().match(/^this/)) { | ||
if (match[MULTIPLIER_WORD_GROUP]) { | ||
return null; | ||
} | ||
return this.extractThisReference(context, match[RELATIVE_WORD_GROUP]); | ||
} | ||
const modifier = match[MODIFIER_WORD_GROUP].toLowerCase().match(/^next/) ? 1 : -1; | ||
const parsedNum = match[MULTIPLIER_WORD_GROUP] ? parseNumberPattern(match[MULTIPLIER_WORD_GROUP]) : 1; | ||
const modifier = match[MODIFIER_WORD_GROUP].toLowerCase(); | ||
const unitWord = match[RELATIVE_WORD_GROUP].toLowerCase(); | ||
const timeunit = TIME_UNIT_DICTIONARY[unitWord]; | ||
if (unitWord.match(/day|week|month|year/i)) { | ||
return this.extractDateReference(context, unitWord, parsedNum * modifier); | ||
} else { | ||
return this.extractTimeReference(context, unitWord, parsedNum * modifier); | ||
if (modifier == "next") { | ||
const timeUnits = {}; | ||
timeUnits[timeunit] = 1; | ||
return ParsingComponents.createRelativeFromRefDate(context.refDate, timeUnits); | ||
} | ||
} | ||
extractTimeReference(context: ParsingContext, timeUnitWord: string, num: number) { | ||
const components = context.createParsingComponents(); | ||
let date = dayjs(context.refDate); | ||
if (timeUnitWord.match(/hour/i)) { | ||
date = date.add(num, "hour"); | ||
components.imply("minute", date.minute()); | ||
components.imply("second", date.second()); | ||
} else if (timeUnitWord.match(/min/i)) { | ||
date = date.add(num, "minute"); | ||
components.assign("minute", date.minute()); | ||
components.imply("second", date.second()); | ||
} else if (timeUnitWord.match(/second/i)) { | ||
date = date.add(num, "second"); | ||
components.assign("second", date.second()); | ||
components.assign("minute", date.minute()); | ||
if (modifier == "last" || modifier == "past") { | ||
const timeUnits = {}; | ||
timeUnits[timeunit] = -1; | ||
return ParsingComponents.createRelativeFromRefDate(context.refDate, timeUnits); | ||
} | ||
components.assign("hour", date.hour()); | ||
components.assign("year", date.year()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("day", date.date()); | ||
return components; | ||
} | ||
extractDateReference(context: ParsingContext, dateUnitWord: string, num: number) { | ||
const components = context.createParsingComponents(); | ||
let date = dayjs(context.refDate); | ||
if (dateUnitWord.match(/day/i)) { | ||
date = date.add(num, "d"); | ||
components.assign("year", date.year()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("day", date.date()); | ||
} else if (dateUnitWord.match(/week/i)) { | ||
date = date.add(num * 7, "d"); | ||
// We don't know the exact date for next/last week so we imply them | ||
components.imply("day", date.date()); | ||
components.imply("month", date.month() + 1); | ||
components.imply("year", date.year()); | ||
} else if (dateUnitWord.match(/month/i)) { | ||
date = date.add(num, "month"); | ||
// We don't know the exact day for next/last month | ||
components.imply("day", date.date()); | ||
components.assign("year", date.year()); | ||
components.assign("month", date.month() + 1); | ||
} else if (dateUnitWord.match(/year/i)) { | ||
date = date.add(num, "year"); | ||
// We don't know the exact day for month on next/last year | ||
components.imply("day", date.date()); | ||
components.imply("month", date.month() + 1); | ||
components.assign("year", date.year()); | ||
} | ||
return components; | ||
} | ||
extractThisReference(context: ParsingContext, relativeWord: string) { | ||
const components = context.createParsingComponents(); | ||
let date = dayjs(context.refDate); | ||
// This week | ||
if (relativeWord.match(/week/i)) { | ||
if (unitWord.match(/week/i)) { | ||
date = date.add(-date.get("d"), "d"); | ||
@@ -117,3 +52,3 @@ components.imply("day", date.date()); | ||
// This month | ||
else if (relativeWord.match(/month/i)) { | ||
else if (unitWord.match(/month/i)) { | ||
date = date.add(-date.date() + 1, "d"); | ||
@@ -126,3 +61,3 @@ components.imply("day", date.date()); | ||
// This year | ||
else if (relativeWord.match(/year/i)) { | ||
else if (unitWord.match(/year/i)) { | ||
date = date.add(-date.date() + 1, "d"); | ||
@@ -129,0 +64,0 @@ date = date.add(-date.month(), "month"); |
@@ -25,5 +25,7 @@ import { Parser, ParsingContext } from "../../../chrono"; | ||
const hour = components.get("hour"); | ||
if (hour > 6 && hour < 12) { | ||
if (hour >= 6 && hour < 12) { | ||
components.assign("hour", components.get("hour") + 12); | ||
components.assign("meridiem", Meridiem.PM); | ||
} else if (hour < 6) { | ||
components.assign("meridiem", Meridiem.AM); | ||
} | ||
@@ -33,6 +35,6 @@ } | ||
if (match[0].endsWith("afternoon")) { | ||
components.assign("meridiem", Meridiem.PM); | ||
const hour = components.get("hour"); | ||
if (hour >= 0 && hour <= 6) { | ||
components.assign("hour", components.get("hour") + 12); | ||
components.assign("meridiem", Meridiem.PM); | ||
} | ||
@@ -42,6 +44,6 @@ } | ||
if (match[0].endsWith("morning")) { | ||
components.assign("meridiem", Meridiem.AM); | ||
const hour = components.get("hour"); | ||
if (hour < 12) { | ||
components.assign("hour", components.get("hour")); | ||
components.assign("meridiem", Meridiem.AM); | ||
} | ||
@@ -48,0 +50,0 @@ } |
@@ -5,2 +5,3 @@ import { Parser, ParsingContext } from "../../../chrono"; | ||
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary"; | ||
import { reverseTimeUnits } from "../../../utils/timeunits"; | ||
@@ -21,9 +22,7 @@ const PATTERN = new RegExp("" + "(" + TIME_UNITS_PATTERN + ")" + "(?:ago|before|earlier)(?=(?:\\W|$))", "i"); | ||
innerExtract(context: ParsingContext, match: RegExpMatchArray) { | ||
const fragments = parseTimeUnits(match[1]); | ||
for (const key in fragments) { | ||
fragments[key] = -fragments[key]; | ||
} | ||
const timeUnits = parseTimeUnits(match[1]); | ||
const outputTimeUnits = reverseTimeUnits(timeUnits); | ||
return ParsingComponents.createRelativeFromRefDate(context.refDate, fragments); | ||
return ParsingComponents.createRelativeFromRefDate(context.refDate, outputTimeUnits); | ||
} | ||
} |
@@ -12,4 +12,2 @@ import { Parser, ParsingContext } from "../../../chrono"; | ||
const STRICT_PATTERN = new RegExp("" + "(" + TIME_UNITS_PATTERN + ")" + "(later|from now)" + "(?=(?:\\W|$))", "i"); | ||
const GROUP_NUM_SUFFIX = 2; | ||
const GROUP_NUM_TIMEUNITS = 1; | ||
@@ -27,7 +25,2 @@ | ||
innerExtract(context: ParsingContext, match: RegExpMatchArray) { | ||
const suffix = match[GROUP_NUM_SUFFIX].toLowerCase().trim(); | ||
if (!suffix) { | ||
return null; | ||
} | ||
const fragments = parseTimeUnits(match[GROUP_NUM_TIMEUNITS]); | ||
@@ -34,0 +27,0 @@ return ParsingComponents.createRelativeFromRefDate(context.refDate, fragments); |
@@ -32,6 +32,2 @@ import { Parser, ParsingContext } from "../../../chrono"; | ||
const offset = WEEKDAY_DICTIONARY[dayOfWeek]; | ||
if (offset === undefined) { | ||
return null; | ||
} | ||
const prefix = match[PREFIX_GROUP]; | ||
@@ -38,0 +34,0 @@ const postfix = match[POSTFIX_GROUP]; |
@@ -1,5 +0,4 @@ | ||
import { Parser, ParsingContext } from "../../../chrono"; | ||
import { ParsingContext } from "../../../chrono"; | ||
import { ParsingComponents } from "../../../results"; | ||
import { WEEKDAY_DICTIONARY } from "../constants"; | ||
import dayjs, { Dayjs } from "dayjs"; | ||
import { matchAnyPattern } from "../../../utils/pattern"; | ||
@@ -6,0 +5,0 @@ import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary"; |
@@ -28,3 +28,3 @@ import { Component, ParsedComponents, ParsedResult } from "./index"; | ||
get(component: Component): number | undefined { | ||
get(component: Component): number | null { | ||
if (component in this.knownValues) { | ||
@@ -38,3 +38,3 @@ return this.knownValues[component]; | ||
return undefined; | ||
return null; | ||
} | ||
@@ -135,3 +135,3 @@ | ||
const targetTimezoneOffset = | ||
this.get("timezoneOffset") !== undefined ? this.get("timezoneOffset") : currentTimezoneOffset; | ||
this.get("timezoneOffset") !== null ? this.get("timezoneOffset") : currentTimezoneOffset; | ||
@@ -161,2 +161,6 @@ const adjustTimezoneOffset = targetTimezoneOffset - currentTimezoneOffset; | ||
components.assign("second", date.second()); | ||
components.assign("day", date.date()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("year", date.year()); | ||
} else { | ||
@@ -166,16 +170,16 @@ components.imply("hour", date.hour()); | ||
components.imply("second", date.second()); | ||
} | ||
if (fragments["d"] || fragments["month"] || fragments["year"]) { | ||
components.assign("day", date.date()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("year", date.year()); | ||
} else { | ||
if (fragments["week"]) { | ||
components.imply("weekday", date.day()); | ||
if (fragments["d"]) { | ||
components.assign("day", date.date()); | ||
components.assign("month", date.month() + 1); | ||
components.assign("year", date.year()); | ||
} else { | ||
if (fragments["week"]) { | ||
components.imply("weekday", date.day()); | ||
} | ||
components.imply("day", date.date()); | ||
components.imply("month", date.month() + 1); | ||
components.imply("year", date.year()); | ||
} | ||
components.imply("day", date.date()); | ||
components.imply("month", date.month() + 1); | ||
components.imply("year", date.year()); | ||
} | ||
@@ -182,0 +186,0 @@ |
@@ -114,2 +114,18 @@ import * as chrono from "../../src/"; | ||
}); | ||
testSingleCase(chrono.casual, "The Deadline is midnight ", new Date(2012, 7, 10, 12), (result) => { | ||
expect(result.text).toBe("midnight"); | ||
expect(result.start.get("year")).toBe(2012); | ||
expect(result.start.get("month")).toBe(8); | ||
expect(result.start.get("day")).toBe(11); | ||
expect(result.start.get("hour")).toBe(0); | ||
}); | ||
testSingleCase(chrono.casual, "The Deadline was midnight ", new Date(2012, 7, 10, 1), (result) => { | ||
expect(result.text).toBe("midnight"); | ||
expect(result.start.get("year")).toBe(2012); | ||
expect(result.start.get("month")).toBe(8); | ||
expect(result.start.get("day")).toBe(10); | ||
expect(result.start.get("hour")).toBe(0); | ||
}); | ||
}); | ||
@@ -122,3 +138,2 @@ | ||
expect(result.start).not.toBeNull(); | ||
expect(result.start.get("year")).toBe(2012); | ||
@@ -131,2 +146,11 @@ expect(result.start.get("month")).toBe(8); | ||
}); | ||
testSingleCase(chrono.casual, "Tomorrow at noon", new Date(2012, 8 - 1, 10, 14), (result) => { | ||
expect(result.start.get("year")).toBe(2012); | ||
expect(result.start.get("month")).toBe(8); | ||
expect(result.start.get("day")).toBe(11); | ||
expect(result.start.get("hour")).toBe(12); | ||
expect(result.start).toBeDate(new Date(2012, 8 - 1, 11, 12)); | ||
}); | ||
}); | ||
@@ -133,0 +157,0 @@ |
import * as chrono from "../../src"; | ||
import { testSingleCase } from "../test_util"; | ||
test("Test - Single Expression", () => { | ||
testSingleCase(chrono, "this week", new Date(2017, 11 - 1, 19), (result, text) => { | ||
test("Test - 'This' expressions", () => { | ||
testSingleCase(chrono, "this week", new Date(2017, 11 - 1, 19, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
@@ -13,3 +13,3 @@ expect(result.start.get("year")).toBe(2017); | ||
testSingleCase(chrono, "this month", new Date(2017, 11 - 1, 19), (result, text) => { | ||
testSingleCase(chrono, "this month", new Date(2017, 11 - 1, 19, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
@@ -22,3 +22,3 @@ expect(result.start.get("year")).toBe(2017); | ||
testSingleCase(chrono, "this month", new Date(2017, 11 - 1, 1), (result, text) => { | ||
testSingleCase(chrono, "this month", new Date(2017, 11 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
@@ -31,3 +31,3 @@ expect(result.start.get("year")).toBe(2017); | ||
testSingleCase(chrono, "this year", new Date(2017, 11 - 1, 19), (result, text) => { | ||
testSingleCase(chrono, "this year", new Date(2017, 11 - 1, 19, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
@@ -39,22 +39,8 @@ expect(result.start.get("year")).toBe(2017); | ||
}); | ||
}); | ||
testSingleCase(chrono, "next week", new Date(2016, 10 - 1, 1), (result, text) => { | ||
test("Test - Past relative expressions", () => { | ||
testSingleCase(chrono, "last week", new Date(2016, 10 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(10); | ||
expect(result.start.get("day")).toBe(8); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "next 2 weeks", new Date(2016, 10 - 1, 1), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(10); | ||
expect(result.start.get("day")).toBe(15); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "last week", new Date(2016, 10 - 1, 1), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(9); | ||
@@ -65,38 +51,14 @@ expect(result.start.get("day")).toBe(24); | ||
testSingleCase(chrono, "last 2 weeks", new Date(2016, 10 - 1, 1), (result, text) => { | ||
testSingleCase(chrono, "lastmonth", new Date(2016, 10 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(9); | ||
expect(result.start.get("day")).toBe(17); | ||
expect(result.start.get("day")).toBe(1); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "last two weeks", new Date(2016, 10 - 1, 1), (result, text) => { | ||
testSingleCase(chrono, "last day", new Date(2016, 10 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(9); | ||
expect(result.start.get("day")).toBe(17); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "next day", new Date(2016, 10 - 1, 1), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(10); | ||
expect(result.start.get("day")).toBe(2); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "next 2 days", new Date(2016, 10 - 1, 1), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(10); | ||
expect(result.start.get("day")).toBe(3); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "last day", new Date(2016, 10 - 1, 1), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(9); | ||
expect(result.start.get("day")).toBe(30); | ||
@@ -106,14 +68,6 @@ expect(result.start.get("hour")).toBe(12); | ||
testSingleCase(chrono, "last 2 days", new Date(2016, 10 - 1, 1), (result, text) => { | ||
testSingleCase(chrono, "last month", new Date(2016, 10 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(9); | ||
expect(result.start.get("day")).toBe(29); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "next month", new Date(2016, 10 - 1, 1), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(11); | ||
expect(result.start.get("day")).toBe(1); | ||
@@ -123,49 +77,35 @@ expect(result.start.get("hour")).toBe(12); | ||
testSingleCase(chrono, "next 2 months", new Date(2016, 10 - 1, 1), (result, text) => { | ||
testSingleCase(chrono, "past week", new Date(2016, 10 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(12); | ||
expect(result.start.get("day")).toBe(1); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "last month", new Date(2016, 10 - 1, 1), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(9); | ||
expect(result.start.get("day")).toBe(1); | ||
expect(result.start.get("day")).toBe(24); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
}); | ||
testSingleCase(chrono, "last 2 months", new Date(2016, 10 - 1, 1), (result, text) => { | ||
test("Test - Future relative expressions", () => { | ||
testSingleCase(chrono, "next week", new Date(2016, 10 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(8); | ||
expect(result.start.get("day")).toBe(1); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "next few weeks", new Date(2016, 10 - 1, 1), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(10); | ||
expect(result.start.get("day")).toBe(22); | ||
expect(result.start.get("day")).toBe(8); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "next four weeks", new Date(2016, 10 - 1, 1), (result, text) => { | ||
testSingleCase(chrono, "next day", new Date(2016, 10 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(10); | ||
expect(result.start.get("day")).toBe(29); | ||
expect(result.start.get("day")).toBe(2); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
testSingleCase(chrono, "past week", new Date(2016, 10 - 1, 1), (result, text) => { | ||
testSingleCase(chrono, "next month", new Date(2016, 10 - 1, 1, 12), (result, text) => { | ||
expect(result.text).toBe(text); | ||
expect(result.start.get("year")).toBe(2016); | ||
expect(result.start.get("month")).toBe(9); | ||
expect(result.start.get("day")).toBe(24); | ||
expect(result.start.get("month")).toBe(11); | ||
expect(result.start.get("day")).toBe(1); | ||
expect(result.start.get("hour")).toBe(12); | ||
}); | ||
}); |
@@ -12,4 +12,4 @@ import { ParsingComponents } from "../src/results"; | ||
// undefined | ||
expect(components.get("weekday")).toBeUndefined(); | ||
// null | ||
expect(components.get("weekday")).toBeNull(); | ||
expect(components.isCertain("weekday")).toBe(false); | ||
@@ -16,0 +16,0 @@ |
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
561394
238
12769