Skip to content

Commit

Permalink
support for "morgennamiddag" and others + "volgende week <day>"
Browse files Browse the repository at this point in the history
  • Loading branch information
JeroenVdb committed Feb 3, 2021
1 parent 3dfbb8d commit 49dbf2f
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 27 deletions.
2 changes: 2 additions & 0 deletions src/locales/nl/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import NLMonthNameParser from "./parsers/NLMonthNameParser";
import NLSlashMonthFormatParser from "./parsers/NLSlashMonthFormatParser";
import NLTimeExpressionParser from "./parsers/NLTimeExpressionParser";
import NLCasualYearMonthDayParser from "./parsers/NLCasualYearMonthDayParser";
import NLCasualDateTimeParser from "./parsers/NLCasualDateTimeParser";

// Shortcuts
export const casual = new Chrono(createCasualConfiguration());
Expand All @@ -30,6 +31,7 @@ export function createCasualConfiguration(littleEndian = true): Configuration {
const option = createConfiguration(false, littleEndian);
option.parsers.unshift(new NLCasualDateParser());
option.parsers.unshift(new NLCasualTimeParser());
option.parsers.unshift(new NLCasualDateTimeParser());
return option;
}

Expand Down
76 changes: 76 additions & 0 deletions src/locales/nl/parsers/NLCasualDateTimeParser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { ParsingContext } from "../../../chrono";
import { ParsingComponents, ParsingResult } from "../../../results";
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
import * as references from "../../../common/casualReferences";
import {Meridiem} from "../../../index";
import {assignSimilarDate, assignTheNextDay} from "../../../utils/dayjs";
import dayjs from "dayjs";

/*
* Find combined words
* - morgenochtend
* - morgenmiddag
* - morgennamiddag
* - morgenavond
* - morgennacht
* - vanochtend
* - vanmiddag
* - vannamiddag
* - vanavond
* - vannacht
* - gisterenochtend
* - gisterenmiddag
* - gisterennamiddag
* - gisterenavond
* - gisterennacht
* */

const DATE_GROUP = 1;
const TIME_OF_DAY_GROUP = 2;

export default class NLCasualDateTimeParser extends AbstractParserWithWordBoundaryChecking {
innerPattern(context: ParsingContext): RegExp {
return /(gisteren|morgen|van)(ochtend|middag|namiddag|avond|nacht)(?=\W|$)/i;
}

innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents | ParsingResult {
const dateText = match[DATE_GROUP].toLowerCase();
const timeText = match[TIME_OF_DAY_GROUP].toLowerCase();
const component = context.createParsingComponents();
const targetDate = dayjs(context.refDate);

switch (dateText) {
case "gisteren":
assignSimilarDate(component, targetDate.add(-1, "day"));
break;
case "van":
assignSimilarDate(component, targetDate);
break;
case "morgen":
assignTheNextDay(component, targetDate);
break;
}

switch (timeText) {
case "ochtend":
component.imply("meridiem", Meridiem.AM);
component.imply("hour", 6);
break;
case "middag":
component.imply("meridiem", Meridiem.AM);
component.imply("hour", 12);
break;
case "namiddag":
component.imply("meridiem", Meridiem.PM);
component.imply("hour", 15);
break;

case "avond":
component.imply("meridiem", Meridiem.PM);
component.imply("hour", 20);
break;
}

return component;
}
}
3 changes: 1 addition & 2 deletions src/locales/nl/parsers/NLCasualTimeParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const MOMENT_GROUP = 2;

export default class NLCasualTimeParser extends AbstractParserWithWordBoundaryChecking {
innerPattern() {
return /(deze)?\s*(namiddag|vanavond|avond|vannacht|middernacht|vanochtend|ochtend|vanmiddag|middag|'s middags|'s avonds|'s ochtends)(?=\W|$)/i;
return /(deze)?\s*(namiddag|avond|middernacht|ochtend|middag|'s middags|'s avonds|'s ochtends)(?=\W|$)/i;
}

innerExtract(context: ParsingContext, match: RegExpMatchArray) {
Expand All @@ -29,7 +29,6 @@ export default class NLCasualTimeParser extends AbstractParserWithWordBoundaryCh
component.imply("hour", 15);
break;

case "vanavond":
case "avond":
case "'s avonds'":
component.imply("meridiem", Meridiem.PM);
Expand Down
6 changes: 2 additions & 4 deletions src/locales/nl/parsers/NLWeekdayParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ import { toDayJSWeekday } from "../../../calculation/weeks";

const PATTERN = new RegExp(
"(?:(?:\\,|\\(|\\()\\s*)?" +
"(?:on\\s*?)?" +
"(?:(deze|vorige|volgende)\\s*)?" +
"(?:op\\s*?)?" +
"(?:(deze|vorige|volgende)\\s*(?:week\\s*)?)?" +
`(${matchAnyPattern(WEEKDAY_DICTIONARY)})` +
"(?:\\s*(?:\\,|\\)|\\)))?" +
"(?:\\s*(deze|vorige|volgende)\\s*week)?" +
"(?=\\W|$)",
"i"
);
Expand Down
90 changes: 80 additions & 10 deletions test/nl/nl_casual.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,90 @@ test("Test - Combined Expression", () => {

expect(result.start).toBeDate(new Date(2012, 7, 10, 17));
});
});

test("Test - Casual combined datetime expressions", () => {
testSingleCase(chrono.nl, "gisterenochtend", 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(9);
expect(result.start.get("hour")).toBe(6);

expect(result.start).toBeDate(new Date(2012, 8 - 1, 9, 6));
});

testSingleCase(chrono.nl, "gisterenmiddag", 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(9);
expect(result.start.get("hour")).toBe(12);

expect(result.start).toBeDate(new Date(2012, 8 - 1, 9, 12));
});

testSingleCase(chrono.nl, "gisterenavond", 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(9);
expect(result.start.get("hour")).toBe(20);

expect(result.start).toBeDate(new Date(2012, 8 - 1, 9, 20));
});

testSingleCase(chrono.nl, "vanochtend", 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(10);
expect(result.start.get("hour")).toBe(6);

expect(result.start).toBeDate(new Date(2012, 8 - 1, 10, 6));
});

// TODO should be "morgenmiddag"
testSingleCase(chrono.nl, "morgen middag", new Date(2012, 8 - 1, 10, 14), (result) => {
testSingleCase(chrono.nl, "vanmiddag", 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(10);
expect(result.start.get("hour")).toBe(12);

expect(result.start).toBeDate(new Date(2012, 8 - 1, 10, 12));
});

testSingleCase(chrono.nl, "vanavond", 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(10);
expect(result.start.get("hour")).toBe(20);

expect(result.start).toBeDate(new Date(2012, 8 - 1, 10, 20));
});

testSingleCase(chrono.nl, "morgenochtend", 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(6);

expect(result.start).toBeDate(new Date(2012, 8 - 1, 11, 6));
});

testSingleCase(chrono.nl, "morgenmiddag", 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));
});
});

testSingleCase(chrono.nl, "morgenavond", 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(20);

expect(result.start).toBeDate(new Date(2012, 8 - 1, 11, 20));
});
})

test("Test - Casual date range", () => {
testSingleCase(chrono.nl, "Het evenement is vandaag - volgende vrijdag", new Date(2012, 7, 4, 12), (result) => {
Expand Down Expand Up @@ -188,13 +261,12 @@ test("Test - Casual date range", () => {
});

test("Test - Casual time implication", () => {
// TODO should be "morgennamiddag"
testSingleCase(
chrono.nl,
"jaarlijks verlof vanaf vandaag tot morgen namiddag",
"jaarlijks verlof vanaf vandaag tot morgennamiddag",
new Date(2012, 8 - 1, 4, 12),
(result) => {
expect(result.text).toBe("vandaag tot morgen namiddag");
expect(result.text).toBe("vandaag tot morgennamiddag");

expect(result.start.get("month")).toBe(8);
expect(result.start.get("day")).toBe(4);
Expand Down Expand Up @@ -287,17 +359,15 @@ test("Test - Random text", () => {
expect(result.start.get("hour")).toBe(20);
});

// TODO: should be "gisterennamiddag"
testSingleCase(chrono.nl, "gisteren namiddag", new Date(2016, 10 - 1, 1), (result, text) => {
testSingleCase(chrono.nl, "gisterennamiddag", 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);
expect(result.start.get("hour")).toBe(15);
});

// TODO: should be "morgenochtend"
testSingleCase(chrono.nl, "morgen ochtend", new Date(2016, 10 - 1, 1, 8), (result, text) => {
testSingleCase(chrono.nl, "morgenochtend", new Date(2016, 10 - 1, 1, 8), (result, text) => {
expect(result.text).toBe(text);
expect(result.start.get("year")).toBe(2016);
expect(result.start.get("month")).toBe(10);
Expand Down
33 changes: 22 additions & 11 deletions test/nl/nl_weekday.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,26 @@ test("Test - Single Expression", function () {
expect(result.start).toBeDate(new Date(2012, 7, 3, 12));
});

// TODO: should be "volgende week vrijdag"
testSingleCase(chrono.nl, "De deadline is vorige vrijdag...", new Date(2012, 7, 12), (result) => {
expect(result.index).toBe(15);
expect(result.text).toBe("vorige vrijdag");

expect(result.start).not.toBeNull();
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("weekday")).toBe(5);

expect(result.start).toBeDate(new Date(2012, 7, 10, 12));
});

testSingleCase(
chrono.nl,
"Laten we een meeting hebben op vrijdag volgende week",
new Date(2015, 3, 18),
"Laten we een meeting hebben op volgende week vrijdag",
new Date(2015, 3, 16),
(result) => {
expect(result.index).toBe(31);
expect(result.text).toBe("vrijdag volgende week");
expect(result.index).toBe(28);
expect(result.text).toBe("op volgende week vrijdag");

expect(result.start).not.toBeNull();
expect(result.start.get("year")).toBe(2015);
Expand All @@ -96,10 +108,9 @@ test("Test - Single Expression", function () {
}
);

// TODO: should be "volgende week dinsdag"
testSingleCase(chrono.nl, "Ik plan een vrije dag op dinsdag, volgende week", new Date(2015, 3, 18), (result) => {
expect(result.index).toBe(25);
expect(result.text).toBe("dinsdag, volgende week");
testSingleCase(chrono.nl, "Ik plan een vrije dag op volgende week dinsdag", new Date(2015, 3, 18), (result) => {
expect(result.index).toBe(22);
expect(result.text).toBe("op volgende week dinsdag");

expect(result.start).not.toBeNull();
expect(result.start.get("year")).toBe(2015);
Expand All @@ -113,8 +124,8 @@ test("Test - Single Expression", function () {

test("Test - Weekday With Casual Time", function () {
testSingleCase(chrono.nl, "Laten we op dinsdag ochtend afspreken", new Date(2015, 3, 18), (result) => {
expect(result.index).toBe(12);
expect(result.text).toBe("dinsdag ochtend");
expect(result.index).toBe(9);
expect(result.text).toBe("op dinsdag ochtend");

expect(result.start).not.toBeNull();
expect(result.start.get("year")).toBe(2015);
Expand Down

0 comments on commit 49dbf2f

Please sign in to comment.