Skip to content

Commit 1fbd73f

Browse files
aznan2Matti Hansson
andauthored
Make date-time validation align with RFC3339 (networknt#508) (networknt#521)
Co-authored-by: Matti Hansson <[email protected]>
1 parent 67bff81 commit 1fbd73f

File tree

4 files changed

+45
-22
lines changed

4 files changed

+45
-22
lines changed

src/main/java/com/networknt/schema/DateTimeValidator.java

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ public class DateTimeValidator extends BaseJsonValidator implements JsonValidato
4040

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

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

8484
boolean isTimeGiven = matcher.group(4) != null;
85-
String timeZoneShiftRegexGroup = matcher.group(9);
86-
boolean isTimeZoneShiftGiven = timeZoneShiftRegexGroup != null;
85+
boolean isOffsetZuluTime = matcher.group(10) != null;
8786
String hour = null;
8887
String minute = null;
8988
String second = null;
9089
String milliseconds = null;
90+
String timeShiftSign = null;
9191
String timeShiftHour = null;
9292
String timeShiftMinute = null;
9393

@@ -96,12 +96,6 @@ private boolean isLegalDateTime(String string) {
9696
return false;
9797
}
9898

99-
if (!isTimeGiven && isTimeZoneShiftGiven) {
100-
logger.error("Invalid date/time format, cannot specify time zone shift" +
101-
" without specifying time: " + string);
102-
return false;
103-
}
104-
10599
if (isTimeGiven) {
106100
hour = matcher.group(5);
107101
minute = matcher.group(6);
@@ -121,16 +115,15 @@ private boolean isLegalDateTime(String string) {
121115
dateTime.append(milliseconds);
122116
pattern.append(".SSS");
123117
}
124-
}
125118

126-
if (isTimeGiven && isTimeZoneShiftGiven) {
127-
if (Character.toUpperCase(timeZoneShiftRegexGroup.charAt(0)) == 'Z') {
119+
if (isOffsetZuluTime) {
128120
dateTime.append('Z');
129121
pattern.append("'Z'");
130122
} else {
131-
timeShiftHour = matcher.group(11);
132-
timeShiftMinute = matcher.group(12);
133-
dateTime.append(matcher.group(10).charAt(0)).append(timeShiftHour).append(':').append(timeShiftMinute);
123+
timeShiftSign = matcher.group(11);
124+
timeShiftHour = matcher.group(12);
125+
timeShiftMinute = matcher.group(13);
126+
dateTime.append(timeShiftSign).append(timeShiftHour).append(':').append(timeShiftMinute);
134127
pattern.append("XXX");
135128
}
136129
}

src/test/resources/draft2019-09/optional/format/date-time.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@
4949
"description": "only RFC3339 not all of ISO 8601 are valid",
5050
"data": "2013-350T01:01:01",
5151
"valid": false
52+
},
53+
{
54+
"description": "an invalid date-time string without offset",
55+
"data": "1963-06-19T08:30:06",
56+
"valid": false
57+
},
58+
{
59+
"description": "an invalid date-time string with only hours in offset",
60+
"data": "1963-06-19T08:30:06+02",
61+
"valid": false
62+
},
63+
{
64+
"description": "an invalid date-time string without colon in offset",
65+
"data": "1963-06-19T08:30:06+0200",
66+
"valid": false
5267
}
5368
]
5469
}

src/test/resources/draft4/optional/format.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
"valid": true
1212
},
1313
{
14-
"description": "a valid date-time string without colon",
14+
"description": "an invalid date-time string without colon",
1515
"data": "2018-07-27T00:00:01.000-0300",
16-
"valid": true
16+
"valid": false
1717
},
1818
{
1919
"description": "a valid date-time string",
@@ -56,14 +56,14 @@
5656
"valid": true
5757
},
5858
{
59-
"description": "an valid date-time string",
59+
"description": "an invalid date-time string",
6060
"data": "1963-12-30T08:30:06.283",
61-
"valid": true
61+
"valid": false
6262
},
6363
{
64-
"description": "an valid date-time string",
64+
"description": "an invalid date-time string",
6565
"data": "1963-12-30T08:30:06",
66-
"valid": true
66+
"valid": false
6767
},
6868
{
6969
"description": "an valid date-time string",

src/test/resources/draft7/optional/format/date-time.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@
4949
"description": "only RFC3339 not all of ISO 8601 are valid",
5050
"data": "2013-350T01:01:01",
5151
"valid": false
52+
},
53+
{
54+
"description": "an invalid date-time string without offset",
55+
"data": "1963-06-19T08:30:06",
56+
"valid": false
57+
},
58+
{
59+
"description": "an invalid date-time string with only hours in offset",
60+
"data": "1963-06-19T08:30:06+02",
61+
"valid": false
62+
},
63+
{
64+
"description": "an invalid date-time string without colon in offset",
65+
"data": "1963-06-19T08:30:06+0200",
66+
"valid": false
5267
}
5368
]
5469
}

0 commit comments

Comments
 (0)