Skip to content

Commit 668b5fe

Browse files
committedMar 2, 2022
[DE] Add casual relative expression parsing
1 parent ef13084 commit 668b5fe

File tree

4 files changed

+168
-2
lines changed

4 files changed

+168
-2
lines changed
 

‎src/locales/de/constants.ts

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { OpUnitType } from "dayjs";
1+
import { OpUnitType, QUnitType } from "dayjs";
22
import { matchAnyPattern, repeatedTimeunitPattern } from "../../utils/pattern";
33
import { findMostLikelyADYear } from "../../calculation/years";
44
import { TimeUnits } from "../../utils/timeunits";
@@ -67,6 +67,10 @@ export const MONTH_DICTIONARY: { [word: string]: number } = {
6767

6868
export const INTEGER_WORD_DICTIONARY: { [word: string]: number } = {
6969
"eins": 1,
70+
"eine": 1,
71+
"einem": 1,
72+
"einen": 1,
73+
"einer": 1,
7074
"zwei": 2,
7175
"drei": 3,
7276
"vier": 4,
@@ -82,7 +86,7 @@ export const INTEGER_WORD_DICTIONARY: { [word: string]: number } = {
8286
"zwoelf": 12,
8387
};
8488

85-
export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType } = {
89+
export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType | QUnitType } = {
8690
sek: "second",
8791
sekunde: "second",
8892
sekunden: "second",
@@ -95,14 +99,24 @@ export const TIME_UNIT_DICTIONARY: { [word: string]: OpUnitType } = {
9599
stunden: "hour",
96100
tag: "d",
97101
tage: "d",
102+
tagen: "d",
98103
woche: "week",
99104
wochen: "week",
100105
monat: "month",
101106
monate: "month",
107+
monaten: "month",
108+
monats: "month",
109+
quartal: "quarter",
110+
quartals: "quarter",
111+
quartale: "quarter",
112+
quartalen: "quarter",
113+
a: "year",
102114
j: "year",
103115
jr: "year",
104116
jahr: "year",
105117
jahre: "year",
118+
jahren: "year",
119+
jahres: "year",
106120
};
107121

108122
//-----------------------------

‎src/locales/de/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import DEMergeDateTimeRefiner from "./refiners/DEMergeDateTimeRefiner";
1111
import DECasualDateParser from "./parsers/DECasualDateParser";
1212
import DECasualTimeParser from "./parsers/DECasualTimeParser";
1313
import DEMonthNameLittleEndianParser from "./parsers/DEMonthNameLittleEndianParser";
14+
import DETimeUnitRelativeFormatParser from "./parsers/DETimeUnitRelativeFormatParser";
1415

1516
// Shortcuts
1617
export const casual = new Chrono(createCasualConfiguration());
@@ -28,6 +29,7 @@ export function createCasualConfiguration(littleEndian = true): Configuration {
2829
const option = createConfiguration(false, littleEndian);
2930
option.parsers.unshift(new DECasualTimeParser());
3031
option.parsers.unshift(new DECasualDateParser());
32+
option.parsers.unshift(new DETimeUnitRelativeFormatParser());
3133
return option;
3234
}
3335

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { ParsingContext } from "../../../chrono";
2+
import { NUMBER_PATTERN, parseNumberPattern, TIME_UNIT_DICTIONARY } from "../constants";
3+
import { ParsingComponents } from "../../../results";
4+
import { AbstractParserWithWordBoundaryChecking } from "../../../common/parsers/AbstractParserWithWordBoundary";
5+
import { reverseTimeUnits } from "../../../utils/timeunits";
6+
import { matchAnyPattern } from "../../../utils/pattern";
7+
8+
export default class DETimeUnitAgoFormatParser extends AbstractParserWithWordBoundaryChecking {
9+
constructor() {
10+
super();
11+
}
12+
13+
innerPattern(): RegExp {
14+
return new RegExp(
15+
`(?:\\s*((?:nächste|kommende|folgende|letzte|vergangene|vorige|vor(?:her|an)gegangene)(?:s|n|m|r)?|vor|in)\\s*)?` +
16+
`(${NUMBER_PATTERN})?` +
17+
`(?:\\s*(nächste|kommende|folgende|letzte|vergangene|vorige|vor(?:her|an)gegangene)(?:s|n|m|r)?)?` +
18+
`\\s*(${matchAnyPattern(TIME_UNIT_DICTIONARY)})`,
19+
"i"
20+
);
21+
}
22+
23+
innerExtract(context: ParsingContext, match: RegExpMatchArray) {
24+
const num = match[2] ? parseNumberPattern(match[2]) : 1;
25+
const unit = TIME_UNIT_DICTIONARY[match[4].toLowerCase()];
26+
let timeUnits = {};
27+
timeUnits[unit] = num;
28+
29+
// Modifier
30+
let modifier = match[1] || match[3] || "";
31+
modifier = modifier.toLowerCase();
32+
if (!modifier) {
33+
return;
34+
}
35+
36+
if (/vor/.test(modifier) || /letzte/.test(modifier) || /vergangen/.test(modifier)) {
37+
timeUnits = reverseTimeUnits(timeUnits);
38+
}
39+
40+
return ParsingComponents.createRelativeFromReference(context.reference, timeUnits);
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import * as chrono from "../../src";
2+
import { testSingleCase, testUnexpectedResult } from "../test_util";
3+
4+
// test("Test - fr - modifier mandatory just after", function () {
5+
// testUnexpectedResult(chrono.de, "le mois d'avril");
6+
//
7+
// testUnexpectedResult(chrono.de, "le mois d'avril prochain");
8+
// });
9+
10+
test("Test - de - relative date", function () {
11+
testSingleCase(chrono.de, "kommende Woche", new Date(2017, 5 - 1, 12), (result, text) => {
12+
expect(result.text).toBe(text);
13+
expect(result.start.get("year")).toBe(2017);
14+
expect(result.start.get("month")).toBe(5);
15+
expect(result.start.get("day")).toBe(19);
16+
});
17+
18+
testSingleCase(chrono.de, "in 2 Wochen", new Date(2017, 5 - 1, 12, 18, 11), (result, text) => {
19+
expect(result.text).toBe(text);
20+
expect(result.start.get("year")).toBe(2017);
21+
expect(result.start.get("month")).toBe(5);
22+
expect(result.start.get("day")).toBe(26);
23+
expect(result.start.get("hour")).toBe(18);
24+
expect(result.start.get("minute")).toBe(11);
25+
});
26+
27+
testSingleCase(chrono.de, "in drei Wochen", new Date(2017, 5 - 1, 12), (result, text) => {
28+
expect(result.text).toBe(text);
29+
expect(result.start.get("year")).toBe(2017);
30+
expect(result.start.get("month")).toBe(6);
31+
expect(result.start.get("day")).toBe(2);
32+
});
33+
34+
testSingleCase(chrono.de, "letzten Monat", new Date(2017, 5 - 1, 12), (result, text) => {
35+
expect(result.text).toBe(text);
36+
expect(result.start.get("year")).toBe(2017);
37+
expect(result.start.get("month")).toBe(4);
38+
expect(result.start.get("day")).toBe(12);
39+
});
40+
41+
testSingleCase(chrono.de, "in den 30 vorangegangenen Tagen", new Date(2017, 5 - 1, 12), (result, text) => {
42+
expect(result.text).toBe("30 vorangegangenen Tagen");
43+
expect(result.start.get("year")).toBe(2017);
44+
expect(result.start.get("month")).toBe(4);
45+
expect(result.start.get("day")).toBe(12);
46+
});
47+
48+
testSingleCase(chrono.de, "die vergangenen 24 Stunden", new Date(2017, 5 - 1, 12, 11, 27), (result, text) => {
49+
expect(result.text).toBe("vergangenen 24 Stunden");
50+
expect(result.start.get("year")).toBe(2017);
51+
expect(result.start.get("month")).toBe(5);
52+
expect(result.start.get("day")).toBe(11);
53+
expect(result.start.get("hour")).toBe(11);
54+
expect(result.start.get("minute")).toBe(27);
55+
});
56+
57+
testSingleCase(chrono.de, "in den folgenden 90 sekunden", new Date(2017, 5 - 1, 12, 11, 27, 3), (result, text) => {
58+
expect(result.text).toBe("folgenden 90 sekunden");
59+
expect(result.start.get("year")).toBe(2017);
60+
expect(result.start.get("month")).toBe(5);
61+
expect(result.start.get("day")).toBe(12);
62+
expect(result.start.get("hour")).toBe(11);
63+
expect(result.start.get("minute")).toBe(28);
64+
expect(result.start.get("second")).toBe(33);
65+
});
66+
67+
testSingleCase(chrono.de, "die letzten acht Minuten", new Date(2017, 5 - 1, 12, 11, 27), (result, text) => {
68+
expect(result.text).toBe("letzten acht Minuten");
69+
expect(result.start.get("year")).toBe(2017);
70+
expect(result.start.get("month")).toBe(5);
71+
expect(result.start.get("day")).toBe(12);
72+
expect(result.start.get("hour")).toBe(11);
73+
expect(result.start.get("minute")).toBe(19);
74+
expect(result.start.get("second")).toBe(0);
75+
});
76+
77+
testSingleCase(chrono.de, "letztes Quartal", new Date(2017, 5 - 1, 12, 11, 27), (result, text) => {
78+
expect(result.text).toBe(text);
79+
expect(result.start.get("year")).toBe(2017);
80+
expect(result.start.get("month")).toBe(2);
81+
expect(result.start.get("day")).toBe(12);
82+
expect(result.start.get("hour")).toBe(11);
83+
expect(result.start.get("minute")).toBe(27);
84+
expect(result.start.get("second")).toBe(0);
85+
86+
expect(result.start.isCertain("month")).toBeFalsy();
87+
expect(result.start.isCertain("day")).toBeFalsy();
88+
expect(result.start.isCertain("hour")).toBeFalsy();
89+
expect(result.start.isCertain("minute")).toBeFalsy();
90+
expect(result.start.isCertain("second")).toBeFalsy();
91+
});
92+
93+
testSingleCase(chrono.de, "kommendes Jahr", new Date(2017, 5 - 1, 12, 11, 27), (result, text) => {
94+
expect(result.text).toBe(text);
95+
expect(result.start.get("year")).toBe(2018);
96+
expect(result.start.get("month")).toBe(5);
97+
expect(result.start.get("day")).toBe(12);
98+
expect(result.start.get("hour")).toBe(11);
99+
expect(result.start.get("minute")).toBe(27);
100+
expect(result.start.get("second")).toBe(0);
101+
102+
expect(result.start.isCertain("month")).toBeFalsy();
103+
expect(result.start.isCertain("day")).toBeFalsy();
104+
expect(result.start.isCertain("hour")).toBeFalsy();
105+
expect(result.start.isCertain("minute")).toBeFalsy();
106+
expect(result.start.isCertain("second")).toBeFalsy();
107+
});
108+
});

0 commit comments

Comments
 (0)
Please sign in to comment.