diff --git a/src/KubernetesClient/KubernetesJson.cs b/src/KubernetesClient/KubernetesJson.cs index 35cfe3ac..3b7d048d 100644 --- a/src/KubernetesClient/KubernetesJson.cs +++ b/src/KubernetesClient/KubernetesJson.cs @@ -34,19 +34,27 @@ public sealed class KubernetesDateTimeOffsetConverter : JsonConverter (m.Value + "000000000").Substring(0, 7 + 1)); // 7 digits + 1 for the dot - if (DateTimeOffset.TryParseExact(str, new[] { RFC3339NanoFormat }, CultureInfo.InvariantCulture, DateTimeStyles.None, out result)) + if (DateTimeOffset.TryParseExact(str, NanoFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out result)) { return result; } @@ -54,7 +62,6 @@ public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConver throw new FormatException($"Unable to parse {originalstr} as RFC3339 RFC3339Micro or RFC3339Nano"); } - public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) { // Output as RFC3339Micro diff --git a/tests/KubernetesClient.Tests/KubernetesJsonTests.cs b/tests/KubernetesClient.Tests/KubernetesJsonTests.cs index e8f19945..38fd0500 100644 --- a/tests/KubernetesClient.Tests/KubernetesJsonTests.cs +++ b/tests/KubernetesClient.Tests/KubernetesJsonTests.cs @@ -169,4 +169,36 @@ public void DateTimeWithFractionalSecondsAlwaysHasSixDigits() // Also verify it doesn't have 5 digits (which would fail in Kubernetes) Assert.DoesNotContain("2025-11-17T22:52:34.96217Z", json); } + + [Fact] + public void DateTimeWithTimezoneOffsetParsesCorrectly() + { + // Test that datetime with explicit timezone offset (e.g., +00:00) is parsed correctly + // This uses the "last resort" general DateTimeOffset parsing fallback + var json = "{\"metadata\":{\"creationTimestamp\":\"2025-12-12T16:16:55.079293+00:00\"}}"; + + var secret = KubernetesJson.Deserialize(json); + + Assert.NotNull(secret.Metadata?.CreationTimestamp); + var dt = secret.Metadata.CreationTimestamp.Value; + + Assert.Equal(2025, dt.Year); + Assert.Equal(12, dt.Month); + Assert.Equal(12, dt.Day); + Assert.Equal(16, dt.Hour); + Assert.Equal(16, dt.Minute); + Assert.Equal(55, dt.Second); + Assert.Equal(79, dt.Millisecond); +#if NET7_0_OR_GREATER + Assert.Equal(293, dt.Microsecond); +#endif + } + + [Fact] + public void DateTimeNonRfc3339FormatIsRejected() + { + var json = "{\"metadata\":{\"creationTimestamp\":\"12/31/2023\"}}"; + + Assert.Throws(() => KubernetesJson.Deserialize(json)); + } }