Skip to content

Commit

Permalink
Make date-time validation align with RFC3339 (networknt#508)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matti Hansson committed Feb 25, 2022
1 parent 67bff81 commit 669e4ee
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 22 deletions.
25 changes: 9 additions & 16 deletions src/main/java/com/networknt/schema/DateTimeValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public class DateTimeValidator extends BaseJsonValidator implements JsonValidato

private static final Pattern RFC3339_PATTERN = Pattern.compile(
"^(\\d{4})-(\\d{2})-(\\d{2})" // yyyy-MM-dd
+ "([Tt](\\d{2}):(\\d{2}):(\\d{2})(\\.\\d+)?)?" // 'T'HH:mm:ss.milliseconds
+ "([Zz]|([+-])(\\d{2}):?(\\d{2}))?");
+ "([Tt](\\d{2}):(\\d{2}):(\\d{2})(\\.\\d+)?" // 'T'HH:mm:ss.milliseconds
+ "(([Zz])|([+-])(\\d{2}):(\\d{2})))?");

public DateTimeValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext, String formatName) {
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.DATETIME, validationContext);
Expand Down Expand Up @@ -82,12 +82,12 @@ private boolean isLegalDateTime(String string) {
pattern.append("yyyy-MM-dd");

boolean isTimeGiven = matcher.group(4) != null;
String timeZoneShiftRegexGroup = matcher.group(9);
boolean isTimeZoneShiftGiven = timeZoneShiftRegexGroup != null;
boolean isOffsetZuluTime = matcher.group(10) != null;
String hour = null;
String minute = null;
String second = null;
String milliseconds = null;
String timeShiftSign = null;
String timeShiftHour = null;
String timeShiftMinute = null;

Expand All @@ -96,12 +96,6 @@ private boolean isLegalDateTime(String string) {
return false;
}

if (!isTimeGiven && isTimeZoneShiftGiven) {
logger.error("Invalid date/time format, cannot specify time zone shift" +
" without specifying time: " + string);
return false;
}

if (isTimeGiven) {
hour = matcher.group(5);
minute = matcher.group(6);
Expand All @@ -121,16 +115,15 @@ private boolean isLegalDateTime(String string) {
dateTime.append(milliseconds);
pattern.append(".SSS");
}
}

if (isTimeGiven && isTimeZoneShiftGiven) {
if (Character.toUpperCase(timeZoneShiftRegexGroup.charAt(0)) == 'Z') {
if (isOffsetZuluTime) {
dateTime.append('Z');
pattern.append("'Z'");
} else {
timeShiftHour = matcher.group(11);
timeShiftMinute = matcher.group(12);
dateTime.append(matcher.group(10).charAt(0)).append(timeShiftHour).append(':').append(timeShiftMinute);
timeShiftSign = matcher.group(11);
timeShiftHour = matcher.group(12);
timeShiftMinute = matcher.group(13);
dateTime.append(timeShiftSign).append(timeShiftHour).append(':').append(timeShiftMinute);
pattern.append("XXX");
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/test/resources/draft2019-09/optional/format/date-time.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350T01:01:01",
"valid": false
},
{
"description": "an invalid date-time string without offset",
"data": "1963-06-19T08:30:06",
"valid": false
},
{
"description": "an invalid date-time string with only hours in offset",
"data": "1963-06-19T08:30:06+02",
"valid": false
},
{
"description": "an invalid date-time string without colon in offset",
"data": "1963-06-19T08:30:06+0200",
"valid": false
}
]
}
Expand Down
12 changes: 6 additions & 6 deletions src/test/resources/draft4/optional/format.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"valid": true
},
{
"description": "a valid date-time string without colon",
"description": "an invalid date-time string without colon",
"data": "2018-07-27T00:00:01.000-0300",
"valid": true
"valid": false
},
{
"description": "a valid date-time string",
Expand Down Expand Up @@ -56,14 +56,14 @@
"valid": true
},
{
"description": "an valid date-time string",
"description": "an invalid date-time string",
"data": "1963-12-30T08:30:06.283",
"valid": true
"valid": false
},
{
"description": "an valid date-time string",
"description": "an invalid date-time string",
"data": "1963-12-30T08:30:06",
"valid": true
"valid": false
},
{
"description": "an valid date-time string",
Expand Down
15 changes: 15 additions & 0 deletions src/test/resources/draft7/optional/format/date-time.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@
"description": "only RFC3339 not all of ISO 8601 are valid",
"data": "2013-350T01:01:01",
"valid": false
},
{
"description": "an invalid date-time string without offset",
"data": "1963-06-19T08:30:06",
"valid": false
},
{
"description": "an invalid date-time string with only hours in offset",
"data": "1963-06-19T08:30:06+02",
"valid": false
},
{
"description": "an invalid date-time string without colon in offset",
"data": "1963-06-19T08:30:06+0200",
"valid": false
}
]
}
Expand Down

0 comments on commit 669e4ee

Please sign in to comment.