Skip to content

Commit

Permalink
Improve regex generation for DateTime parser
Browse files Browse the repository at this point in the history
If there are two adjacent integer definitions for date/time fields
in the picture string without any extra markup between them,
then the generated regex must precisely define the number of digits in the first field.

Signed-off-by: Andrew Coleman <[email protected]>
  • Loading branch information
andrew-coleman authored and mattbaileyuk committed Jan 11, 2025
1 parent 2ed0395 commit 2dd49c6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
25 changes: 12 additions & 13 deletions src/datetime.js
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ const dateTime = (function () {
def.integerFormat.mandatoryDigits = def.width.min;
}
}
if ('YMD'.indexOf(def.component) !== -1) {
if (def.component === 'Y') {
// §9.8.4.4
def.n = -1;
if (def.width && def.width.max !== undefined) {
Expand All @@ -625,6 +625,11 @@ const dateTime = (function () {
}
}
}
// if the previous part is also an integer with no intervening markup, then its width for parsing must be precisely defined
const previousPart = spec[spec.length - 1];
if (previousPart && previousPart.integerFormat) {
previousPart.integerFormat.parseWidth = previousPart.integerFormat.mandatoryDigits;
}
}
if (def.component === 'Z' || def.component === 'z') {
def.integerFormat = analyseIntegerPicture(def.presentation1);
Expand Down Expand Up @@ -990,7 +995,6 @@ const dateTime = (function () {
return offsetHours * 60 + offsetMinutes;
};
} else if (part.integerFormat) {
part.integerFormat.n = part.n;
res = generateRegex(part.integerFormat);
} else {
// must be a month or day name
Expand Down Expand Up @@ -1035,16 +1039,6 @@ const dateTime = (function () {
} else { // type === 'integer'
matcher.type = 'integer';
const isUpper = formatSpec.case === tcase.UPPER;
let occurrences;
if(formatSpec.n && formatSpec.n > 0){
if(formatSpec.optionalDigits === 0){
occurrences = `{${formatSpec.n}}`;
} else {
occurrences = `{${formatSpec.n - formatSpec.optionalDigits},${formatSpec.n}}`;
}
} else {
occurrences = '+';
}

switch (formatSpec.primary) {
case formats.LETTERS:
Expand All @@ -1066,7 +1060,12 @@ const dateTime = (function () {
};
break;
case formats.DECIMAL:
matcher.regex = `[0-9]${occurrences}`;
matcher.regex = '[0-9]';
if (formatSpec.parseWidth) {
matcher.regex += `{${formatSpec.parseWidth}}`;
} else {
matcher.regex += '+';
}
if (formatSpec.ordinal) {
// ordinals
matcher.regex += '(?:th|st|nd|rd)';
Expand Down
6 changes: 6 additions & 0 deletions test/test-suite/groups/function-tomillis/case013.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"expr": "$toMillis('2024-01-01T12:38:49Z') = $toMillis('20240101123849', '[Y0000][M00][D00][H00][m00][s00]')",
"data": null,
"bindings": {},
"result": true
}

0 comments on commit 2dd49c6

Please sign in to comment.