Skip to content

Commit a6a44a7

Browse files
committed
fix: date time and date time offset shifting zones
perf: avoid round trip serialization Signed-off-by: Vincent Biret <[email protected]>
1 parent cce2495 commit a6a44a7

File tree

1 file changed

+45
-22
lines changed

1 file changed

+45
-22
lines changed

src/Microsoft.OpenApi/Writers/OpenApiWriterAnyExtensions.cs

+45-22
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4+
using System;
45
using System.Collections.Generic;
6+
using System.Globalization;
57
using System.Text.Json;
68
using System.Text.Json.Nodes;
79
using Microsoft.OpenApi.Any;
@@ -49,16 +51,15 @@ public static void WriteExtensions(this IOpenApiWriter writer, IDictionary<strin
4951
/// <param name="node">The JsonNode value</param>
5052
public static void WriteAny(this IOpenApiWriter writer, JsonNode node)
5153
{
52-
Utils.CheckArgumentNull(writer);;
54+
Utils.CheckArgumentNull(writer);
5355

5456
if (node == null)
5557
{
5658
writer.WriteNull();
5759
return;
5860
}
5961

60-
var element = JsonDocument.Parse(node.ToJsonString()).RootElement;
61-
switch (element.ValueKind)
62+
switch (node.GetValueKind())
6263
{
6364
case JsonValueKind.Array: // Array
6465
writer.WriteArray(node as JsonArray);
@@ -67,13 +68,13 @@ public static void WriteAny(this IOpenApiWriter writer, JsonNode node)
6768
writer.WriteObject(node as JsonObject);
6869
break;
6970
case JsonValueKind.String: // Primitive
70-
writer.WritePrimitive(element);
71+
writer.WritePrimitive(node);
7172
break;
7273
case JsonValueKind.Number: // Primitive
73-
writer.WritePrimitive(element);
74+
writer.WritePrimitive(node);
7475
break;
7576
case JsonValueKind.True or JsonValueKind.False: // Primitive
76-
writer.WritePrimitive(element);
77+
writer.WritePrimitive(node);
7778
break;
7879
case JsonValueKind.Null: // null
7980
writer.WriteNull();
@@ -108,52 +109,74 @@ private static void WriteObject(this IOpenApiWriter writer, JsonObject entity)
108109
writer.WriteEndObject();
109110
}
110111

111-
private static void WritePrimitive(this IOpenApiWriter writer, JsonElement primitive)
112+
private static void WritePrimitive(this IOpenApiWriter writer, JsonNode primitive)
112113
{
113114
if (writer == null)
114115
{
115116
Utils.CheckArgumentNull(writer);
116117
}
117118

118-
if (primitive.ValueKind == JsonValueKind.String)
119+
var valueKind = primitive.GetValueKind();
120+
121+
if (valueKind == JsonValueKind.String && primitive is JsonValue jsonStrValue)
119122
{
120-
// check whether string is actual string or date time object
121-
if (primitive.TryGetDateTime(out var dateTime))
123+
if (jsonStrValue.TryGetValue<DateTimeOffset>(out var dto))
122124
{
123-
writer.WriteValue(dateTime);
125+
writer.WriteValue(dto);
124126
}
125-
else if (primitive.TryGetDateTimeOffset(out var dateTimeOffset))
127+
else if (jsonStrValue.TryGetValue<DateTime>(out var dt))
126128
{
127-
writer.WriteValue(dateTimeOffset);
129+
writer.WriteValue(dt);
128130
}
129-
else
131+
else if (jsonStrValue.TryGetValue<string>(out var strValue))
130132
{
131-
writer.WriteValue(primitive.GetString());
133+
// check whether string is actual string or date time object
134+
if (DateTimeOffset.TryParse(strValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTimeOffset))
135+
{
136+
writer.WriteValue(dateTimeOffset);
137+
}
138+
else if (DateTime.TryParse(strValue, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var dateTime))
139+
{ // order matters, DTO needs to be checked first!!!
140+
writer.WriteValue(dateTime);
141+
}
142+
else
143+
{
144+
writer.WriteValue(strValue);
145+
}
132146
}
133147
}
134148

135-
if (primitive.ValueKind == JsonValueKind.Number)
149+
else if (valueKind == JsonValueKind.Number && primitive is JsonValue jsonValue)
136150
{
137-
if (primitive.TryGetDecimal(out var decimalValue))
151+
152+
if (jsonValue.TryGetValue<decimal>(out var decimalValue))
138153
{
139154
writer.WriteValue(decimalValue);
140155
}
141-
else if (primitive.TryGetDouble(out var doubleValue))
156+
else if (jsonValue.TryGetValue<double>(out var doubleValue))
142157
{
143158
writer.WriteValue(doubleValue);
144159
}
145-
else if (primitive.TryGetInt64(out var longValue))
160+
else if (jsonValue.TryGetValue<float>(out var floatValue))
161+
{
162+
writer.WriteValue(floatValue);
163+
}
164+
else if (jsonValue.TryGetValue<long>(out var longValue))
146165
{
147166
writer.WriteValue(longValue);
148167
}
149-
else if (primitive.TryGetInt32(out var intValue))
168+
else if (jsonValue.TryGetValue<int>(out var intValue))
150169
{
151170
writer.WriteValue(intValue);
152171
}
153172
}
154-
if (primitive.ValueKind is JsonValueKind.True or JsonValueKind.False)
173+
else if (valueKind is JsonValueKind.False)
174+
{
175+
writer.WriteValue(false);
176+
}
177+
else if (valueKind is JsonValueKind.True)
155178
{
156-
writer.WriteValue(primitive.GetBoolean());
179+
writer.WriteValue(true);
157180
}
158181
}
159182
}

0 commit comments

Comments
 (0)