Skip to content

Commit a2c9e7b

Browse files
Unify the JsonDocument and Utf8JsonReader handling of DateTime/Offset (#113929)
Since so much of the code is identical, move it to JsonReaderHelper Closes #28931 Co-authored-by: Pranav Senthilnathan <[email protected]>
1 parent 5fab56b commit a2c9e7b

File tree

3 files changed

+56
-86
lines changed

3 files changed

+56
-86
lines changed

src/libraries/System.Text.Json/src/System/Text/Json/Document/JsonDocument.cs

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -666,28 +666,7 @@ internal bool TryGetValue(int index, out DateTime value)
666666
ReadOnlySpan<byte> data = _utf8Json.Span;
667667
ReadOnlySpan<byte> segment = data.Slice(row.Location, row.SizeOrLength);
668668

669-
if (!JsonHelpers.IsValidDateTimeOffsetParseLength(segment.Length))
670-
{
671-
value = default;
672-
return false;
673-
}
674-
675-
// Segment needs to be unescaped
676-
if (row.HasComplexChildren)
677-
{
678-
return JsonReaderHelper.TryGetEscapedDateTime(segment, out value);
679-
}
680-
681-
Debug.Assert(segment.IndexOf(JsonConstants.BackSlash) == -1);
682-
683-
if (JsonHelpers.TryParseAsISO(segment, out DateTime tmp))
684-
{
685-
value = tmp;
686-
return true;
687-
}
688-
689-
value = default;
690-
return false;
669+
return JsonReaderHelper.TryGetValue(segment, row.HasComplexChildren, out value);
691670
}
692671

693672
internal bool TryGetValue(int index, out DateTimeOffset value)
@@ -701,28 +680,7 @@ internal bool TryGetValue(int index, out DateTimeOffset value)
701680
ReadOnlySpan<byte> data = _utf8Json.Span;
702681
ReadOnlySpan<byte> segment = data.Slice(row.Location, row.SizeOrLength);
703682

704-
if (!JsonHelpers.IsValidDateTimeOffsetParseLength(segment.Length))
705-
{
706-
value = default;
707-
return false;
708-
}
709-
710-
// Segment needs to be unescaped
711-
if (row.HasComplexChildren)
712-
{
713-
return JsonReaderHelper.TryGetEscapedDateTimeOffset(segment, out value);
714-
}
715-
716-
Debug.Assert(segment.IndexOf(JsonConstants.BackSlash) == -1);
717-
718-
if (JsonHelpers.TryParseAsISO(segment, out DateTimeOffset tmp))
719-
{
720-
value = tmp;
721-
return true;
722-
}
723-
724-
value = default;
725-
return false;
683+
return JsonReaderHelper.TryGetValue(segment, row.HasComplexChildren, out value);
726684
}
727685

728686
internal bool TryGetValue(int index, out Guid value)

src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,32 @@ public static bool IsTokenTypePrimitive(JsonTokenType tokenType) =>
7979
// Otherwise, return false.
8080
public static bool IsHexDigit(byte nextByte) => HexConverter.IsHexChar(nextByte);
8181

82+
public static bool TryGetValue(ReadOnlySpan<byte> segment, bool isEscaped, out DateTime value)
83+
{
84+
if (!JsonHelpers.IsValidDateTimeOffsetParseLength(segment.Length))
85+
{
86+
value = default;
87+
return false;
88+
}
89+
90+
// Segment needs to be unescaped
91+
if (isEscaped)
92+
{
93+
return TryGetEscapedDateTime(segment, out value);
94+
}
95+
96+
Debug.Assert(segment.IndexOf(JsonConstants.BackSlash) == -1);
97+
98+
if (JsonHelpers.TryParseAsISO(segment, out DateTime tmp))
99+
{
100+
value = tmp;
101+
return true;
102+
}
103+
104+
value = default;
105+
return false;
106+
}
107+
82108
public static bool TryGetEscapedDateTime(ReadOnlySpan<byte> source, out DateTime value)
83109
{
84110
Debug.Assert(source.Length <= JsonConstants.MaximumEscapedDateTimeOffsetParseLength);
@@ -101,6 +127,32 @@ public static bool TryGetEscapedDateTime(ReadOnlySpan<byte> source, out DateTime
101127
return false;
102128
}
103129

130+
public static bool TryGetValue(ReadOnlySpan<byte> segment, bool isEscaped, out DateTimeOffset value)
131+
{
132+
if (!JsonHelpers.IsValidDateTimeOffsetParseLength(segment.Length))
133+
{
134+
value = default;
135+
return false;
136+
}
137+
138+
// Segment needs to be unescaped
139+
if (isEscaped)
140+
{
141+
return TryGetEscapedDateTimeOffset(segment, out value);
142+
}
143+
144+
Debug.Assert(segment.IndexOf(JsonConstants.BackSlash) == -1);
145+
146+
if (JsonHelpers.TryParseAsISO(segment, out DateTimeOffset tmp))
147+
{
148+
value = tmp;
149+
return true;
150+
}
151+
152+
value = default;
153+
return false;
154+
}
155+
104156
public static bool TryGetEscapedDateTimeOffset(ReadOnlySpan<byte> source, out DateTimeOffset value)
105157
{
106158
Debug.Assert(source.Length <= JsonConstants.MaximumEscapedDateTimeOffsetParseLength);

src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,30 +1260,10 @@ internal bool TryGetDateTimeCore(out DateTime value)
12601260
}
12611261
else
12621262
{
1263-
if (!JsonHelpers.IsInRangeInclusive(ValueSpan.Length, JsonConstants.MinimumDateTimeParseLength, JsonConstants.MaximumEscapedDateTimeOffsetParseLength))
1264-
{
1265-
value = default;
1266-
return false;
1267-
}
1268-
12691263
span = ValueSpan;
12701264
}
12711265

1272-
if (ValueIsEscaped)
1273-
{
1274-
return JsonReaderHelper.TryGetEscapedDateTime(span, out value);
1275-
}
1276-
1277-
Debug.Assert(span.IndexOf(JsonConstants.BackSlash) == -1);
1278-
1279-
if (JsonHelpers.TryParseAsISO(span, out DateTime tmp))
1280-
{
1281-
value = tmp;
1282-
return true;
1283-
}
1284-
1285-
value = default;
1286-
return false;
1266+
return JsonReaderHelper.TryGetValue(span, ValueIsEscaped, out value);
12871267
}
12881268

12891269
/// <summary>
@@ -1325,30 +1305,10 @@ internal bool TryGetDateTimeOffsetCore(out DateTimeOffset value)
13251305
}
13261306
else
13271307
{
1328-
if (!JsonHelpers.IsInRangeInclusive(ValueSpan.Length, JsonConstants.MinimumDateTimeParseLength, JsonConstants.MaximumEscapedDateTimeOffsetParseLength))
1329-
{
1330-
value = default;
1331-
return false;
1332-
}
1333-
13341308
span = ValueSpan;
13351309
}
13361310

1337-
if (ValueIsEscaped)
1338-
{
1339-
return JsonReaderHelper.TryGetEscapedDateTimeOffset(span, out value);
1340-
}
1341-
1342-
Debug.Assert(span.IndexOf(JsonConstants.BackSlash) == -1);
1343-
1344-
if (JsonHelpers.TryParseAsISO(span, out DateTimeOffset tmp))
1345-
{
1346-
value = tmp;
1347-
return true;
1348-
}
1349-
1350-
value = default;
1351-
return false;
1311+
return JsonReaderHelper.TryGetValue(span, ValueIsEscaped, out value);
13521312
}
13531313

13541314
/// <summary>

0 commit comments

Comments
 (0)