Skip to content

Commit cbb928d

Browse files
sanxing-chentellarin
authored andcommitted
Support "as early/late as" as a modifier for datetime entities (#799)
1 parent 0344020 commit cbb928d

File tree

7 files changed

+189
-9
lines changed

7 files changed

+189
-9
lines changed

.NET/Microsoft.Recognizers.Definitions/English/DateTimeDefinitions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,9 @@ public static class DateTimeDefinitions
191191
public const string AMTimeRegex = @"(?<am>morning)";
192192
public const string PMTimeRegex = @"\b(?<pm>afternoon|evening|night)\b";
193193
public const string InclusiveModPrepositions = @"(?<include>((on|in|at)\s+or\s+)|(\s+or\s+(on|in|at)))";
194-
public static readonly string BeforeRegex = $@"(\b{InclusiveModPrepositions}?(before|in advance of|prior to|(no later|earlier|sooner) than|ending (with|on)|by|till|til|until){InclusiveModPrepositions}?\b\s*)|(?<!\w|>)((?<include><=)|<)";
194+
public static readonly string BeforeRegex = $@"(\b{InclusiveModPrepositions}?(before|in\s+advance\s+of|prior\s+to|(no\s+later|earlier|sooner)\s+than|ending\s+(with|on)|by|till|til|until|(?<include>as\s+late\s+as)){InclusiveModPrepositions}?\b\s*)|(?<!\w|>)((?<include><=)|<)";
195195
public static readonly string AfterRegex = $@"(\b{InclusiveModPrepositions}?(after(?!\s+or equal to)|(?<!no\s+)later than){InclusiveModPrepositions}?\b\s*)|(?<!\w|<)((?<include>>=)|>)";
196-
public const string SinceRegex = @"(\b(since|after or equal to|starting (from|on|with))\b\s*)|(?<!\w|<)(>=)";
196+
public const string SinceRegex = @"(\b(since|after\s+or\s+equal\s+to|starting\s+(from|on|with)|as\s+early\s+as)\b\s*)|(?<!\w|<)(>=)";
197197
public const string AroundRegex = @"(\b(around|circa)\s*\b)";
198198
public const string AgoRegex = @"\b(ago|before (?<day>yesterday|today))\b";
199199
public const string LaterRegex = @"\b(later|from now|(from|after) (?<day>tomorrow|tmr|today))\b";

.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseDatePeriodParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ private DateTimeResolutionResult ParseDuration(string text, DateObject reference
12271227
switch (durationUnit)
12281228
{
12291229
case "W":
1230-
var diff = 7 - (((int)beginDate.DayOfWeek) == 0 ? 7 : (int)beginDate.DayOfWeek);
1230+
var diff = 7 - ((int)beginDate.DayOfWeek == 0 ? 7 : (int)beginDate.DayOfWeek);
12311231
endDate = beginDate.AddDays(diff);
12321232
timex = "P" + diff + "D";
12331233
if (diff == 0)

JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ export namespace EnglishDateTime {
182182
export const AMTimeRegex = `(?<am>morning)`;
183183
export const PMTimeRegex = `\\b(?<pm>afternoon|evening|night)\\b`;
184184
export const InclusiveModPrepositions = `(?<include>((on|in|at)\\s+or\\s+)|(\\s+or\\s+(on|in|at)))`;
185-
export const BeforeRegex = `(\\b${InclusiveModPrepositions}?(before|in advance of|prior to|(no later|earlier|sooner) than|ending (with|on)|by|till|til|until)${InclusiveModPrepositions}?\\b\\s*)|(?<!\\w|>)((?<include><=)|<)`;
185+
export const BeforeRegex = `(\\b${InclusiveModPrepositions}?(before|in\\s+advance\\s+of|prior\\s+to|(no\\s+later|earlier|sooner)\\s+than|ending\\s+(with|on)|by|till|til|until|(?<include>as\\s+late\\s+as))${InclusiveModPrepositions}?\\b\\s*)|(?<!\\w|>)((?<include><=)|<)`;
186186
export const AfterRegex = `(\\b${InclusiveModPrepositions}?(after(?!\\s+or equal to)|(?<!no\\s+)later than)${InclusiveModPrepositions}?\\b\\s*)|(?<!\\w|<)((?<include>>=)|>)`;
187-
export const SinceRegex = `(\\b(since|after or equal to|starting (from|on|with))\\b\\s*)|(?<!\\w|<)(>=)`;
187+
export const SinceRegex = `(\\b(since|after\\s+or\\s+equal\\s+to|starting\\s+(from|on|with)|as\\s+early\\s+as)\\b\\s*)|(?<!\\w|<)(>=)`;
188188
export const AroundRegex = `(\\b(around|circa)\\s*\\b)`;
189189
export const AgoRegex = `\\b(ago|before (?<day>yesterday|today))\\b`;
190190
export const LaterRegex = `\\b(later|from now|(from|after) (?<day>tomorrow|tmr|today))\\b`;

Patterns/English/English-DateTime.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,13 +438,13 @@ PMTimeRegex: !simpleRegex
438438
InclusiveModPrepositions: !simpleRegex
439439
def: (?<include>((on|in|at)\s+or\s+)|(\s+or\s+(on|in|at)))
440440
BeforeRegex: !nestedRegex
441-
def: (\b{InclusiveModPrepositions}?(before|in advance of|prior to|(no later|earlier|sooner) than|ending (with|on)|by|till|til|until){InclusiveModPrepositions}?\b\s*)|(?<!\w|>)((?<include><=)|<)
441+
def: (\b{InclusiveModPrepositions}?(before|in\s+advance\s+of|prior\s+to|(no\s+later|earlier|sooner)\s+than|ending\s+(with|on)|by|till|til|until|(?<include>as\s+late\s+as)){InclusiveModPrepositions}?\b\s*)|(?<!\w|>)((?<include><=)|<)
442442
references: [ InclusiveModPrepositions ]
443443
AfterRegex: !nestedRegex
444444
def: (\b{InclusiveModPrepositions}?(after(?!\s+or equal to)|(?<!no\s+)later than){InclusiveModPrepositions}?\b\s*)|(?<!\w|<)((?<include>>=)|>)
445445
references: [ InclusiveModPrepositions ]
446446
SinceRegex: !simpleRegex
447-
def: (\b(since|after or equal to|starting (from|on|with))\b\s*)|(?<!\w|<)(>=)
447+
def: (\b(since|after\s+or\s+equal\s+to|starting\s+(from|on|with)|as\s+early\s+as)\b\s*)|(?<!\w|<)(>=)
448448
AroundRegex: !simpleRegex
449449
def: (\b(around|circa)\s*\b)
450450
AgoRegex: !simpleRegex

Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ class EnglishDateTime:
183183
AMTimeRegex = f'(?<am>morning)'
184184
PMTimeRegex = f'\\b(?<pm>afternoon|evening|night)\\b'
185185
InclusiveModPrepositions = f'(?<include>((on|in|at)\\s+or\\s+)|(\\s+or\\s+(on|in|at)))'
186-
BeforeRegex = f'(\\b{InclusiveModPrepositions}?(before|in advance of|prior to|(no later|earlier|sooner) than|ending (with|on)|by|till|til|until){InclusiveModPrepositions}?\\b\\s*)|(?<!\\w|>)((?<include><=)|<)'
186+
BeforeRegex = f'(\\b{InclusiveModPrepositions}?(before|in\\s+advance\\s+of|prior\\s+to|(no\\s+later|earlier|sooner)\\s+than|ending\\s+(with|on)|by|till|til|until|(?<include>as\\s+late\\s+as)){InclusiveModPrepositions}?\\b\\s*)|(?<!\\w|>)((?<include><=)|<)'
187187
AfterRegex = f'(\\b{InclusiveModPrepositions}?(after(?!\\s+or equal to)|(?<!no\\s+)later than){InclusiveModPrepositions}?\\b\\s*)|(?<!\\w|<)((?<include>>=)|>)'
188-
SinceRegex = f'(\\b(since|after or equal to|starting (from|on|with))\\b\\s*)|(?<!\\w|<)(>=)'
188+
SinceRegex = f'(\\b(since|after\\s+or\\s+equal\\s+to|starting\\s+(from|on|with)|as\\s+early\\s+as)\\b\\s*)|(?<!\\w|<)(>=)'
189189
AroundRegex = f'(\\b(around|circa)\\s*\\b)'
190190
AgoRegex = f'\\b(ago|before (?<day>yesterday|today))\\b'
191191
LaterRegex = f'\\b(later|from now|(from|after) (?<day>tomorrow|tmr|today))\\b'

Specs/DateTime/English/DateTimeModel.json

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6078,5 +6078,95 @@
60786078
}
60796079
}
60806080
]
6081+
},
6082+
{
6083+
"Input": "Let's meet this week as early as 7:00 am",
6084+
"Context": {
6085+
"ReferenceDateTime": "2018-08-17T15:00:00"
6086+
},
6087+
"Results": [
6088+
{
6089+
"Text": "this week",
6090+
"Start": 11,
6091+
"End": 19,
6092+
"TypeName": "datetimeV2.daterange",
6093+
"Resolution": {
6094+
"values": [
6095+
{
6096+
"timex": "2018-W33",
6097+
"type": "daterange",
6098+
"start": "2018-08-13",
6099+
"end": "2018-08-20"
6100+
}
6101+
]
6102+
}
6103+
},
6104+
{
6105+
"Text": "as early as 7:00 am",
6106+
"Start": 21,
6107+
"End": 39,
6108+
"TypeName": "datetimeV2.timerange",
6109+
"Resolution": {
6110+
"values": [
6111+
{
6112+
"timex": "T07:00",
6113+
"Mod": "since",
6114+
"type": "timerange",
6115+
"start": "07:00:00"
6116+
}
6117+
]
6118+
}
6119+
}
6120+
]
6121+
},
6122+
{
6123+
"Input": "I'll leave as late as 7:00 am",
6124+
"Context": {
6125+
"ReferenceDateTime": "2018-08-17T15:00:00"
6126+
},
6127+
"NotSupported": "javascript, python",
6128+
"Results": [
6129+
{
6130+
"Text": "as late as 7:00 am",
6131+
"Start": 11,
6132+
"End": 28,
6133+
"TypeName": "datetimeV2.timerange",
6134+
"Resolution": {
6135+
"values": [
6136+
{
6137+
"timex": "T07:00",
6138+
"Mod": "until",
6139+
"type": "timerange",
6140+
"end": "07:00:00"
6141+
}
6142+
]
6143+
}
6144+
}
6145+
]
6146+
},
6147+
{
6148+
"Input": "I'll leave as late as tomorrow.",
6149+
"Context": {
6150+
"ReferenceDateTime": "2018-08-17T15:00:00"
6151+
},
6152+
"NotSupported": "javascript, python",
6153+
"Results": [
6154+
{
6155+
"Text": "as late as tomorrow",
6156+
"Start": 11,
6157+
"End": 29,
6158+
"TypeName": "datetimeV2.daterange",
6159+
"Resolution": {
6160+
"values": [
6161+
{
6162+
"timex": "2018-08-18",
6163+
"Mod": "until",
6164+
"type": "daterange",
6165+
"end": "2018-08-18"
6166+
}
6167+
]
6168+
}
6169+
}
6170+
]
60816171
}
60826172
]

Specs/DateTime/English/DateTimeModelComplexCalendar.json

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5091,5 +5091,95 @@
50915091
}
50925092
}
50935093
]
5094+
},
5095+
{
5096+
"Input": "Let's meet this week as early as 7:00 am",
5097+
"Context": {
5098+
"ReferenceDateTime": "2018-08-17T15:00:00"
5099+
},
5100+
"Results": [
5101+
{
5102+
"Text": "this week",
5103+
"Start": 11,
5104+
"End": 19,
5105+
"TypeName": "datetimeV2.daterange",
5106+
"Resolution": {
5107+
"values": [
5108+
{
5109+
"timex": "2018-W33",
5110+
"type": "daterange",
5111+
"start": "2018-08-13",
5112+
"end": "2018-08-20"
5113+
}
5114+
]
5115+
}
5116+
},
5117+
{
5118+
"Text": "as early as 7:00 am",
5119+
"Start": 21,
5120+
"End": 39,
5121+
"TypeName": "datetimeV2.timerange",
5122+
"Resolution": {
5123+
"values": [
5124+
{
5125+
"timex": "T07:00",
5126+
"Mod": "since",
5127+
"type": "timerange",
5128+
"start": "07:00:00"
5129+
}
5130+
]
5131+
}
5132+
}
5133+
]
5134+
},
5135+
{
5136+
"Input": "I'll leave as late as 7:00 am",
5137+
"Context": {
5138+
"ReferenceDateTime": "2018-08-17T15:00:00"
5139+
},
5140+
"NotSupported": "javascript, python",
5141+
"Results": [
5142+
{
5143+
"Text": "as late as 7:00 am",
5144+
"Start": 11,
5145+
"End": 28,
5146+
"TypeName": "datetimeV2.timerange",
5147+
"Resolution": {
5148+
"values": [
5149+
{
5150+
"timex": "T07:00",
5151+
"Mod": "until",
5152+
"type": "timerange",
5153+
"end": "07:00:00"
5154+
}
5155+
]
5156+
}
5157+
}
5158+
]
5159+
},
5160+
{
5161+
"Input": "I'll leave as late as tomorrow.",
5162+
"Context": {
5163+
"ReferenceDateTime": "2018-08-17T15:00:00"
5164+
},
5165+
"NotSupported": "javascript, python",
5166+
"Results": [
5167+
{
5168+
"Text": "as late as tomorrow",
5169+
"Start": 11,
5170+
"End": 29,
5171+
"TypeName": "datetimeV2.daterange",
5172+
"Resolution": {
5173+
"values": [
5174+
{
5175+
"timex": "2018-08-18",
5176+
"Mod": "until",
5177+
"type": "daterange",
5178+
"end": "2018-08-18"
5179+
}
5180+
]
5181+
}
5182+
}
5183+
]
50945184
}
50955185
]

0 commit comments

Comments
 (0)