-
Notifications
You must be signed in to change notification settings - Fork 306
Fix datetime serialization to always output 6 decimal places for microseconds #1687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…tional seconds Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
tg123
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/LGTM
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: Copilot, tg123 The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes a datetime serialization bug where fractional seconds were being trimmed instead of padded to exactly 6 decimal places, causing Kubernetes API BadRequest errors. The Kubernetes API strictly requires RFC3339Micro format with exactly 6 fractional second digits when fractional seconds are present.
Key Changes:
- Modified
KubernetesDateTimeOffsetConverter.Writeto check for fractional seconds via ticks and consistently format with 6 decimal places when present - Added comprehensive test to verify 6-digit fractional second serialization
- Maintained backward compatibility by omitting fractional part entirely when no fractional seconds exist
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/KubernetesClient/KubernetesJson.cs | Replaced TrimEnd approach with conditional formatting: RFC3339MicroFormat (6 digits) when fractional seconds exist, no fractional part when they don't |
| tests/KubernetesClient.Tests/KubernetesJsonTests.cs | Added test verifying datetime with 5-digit precision serializes to exactly 6 decimal places (.962170 not .96217) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [Fact] | ||
| public void DateTimeWithFractionalSecondsAlwaysHasSixDigits() | ||
| { | ||
| // Test that datetime fields with fractional seconds always output exactly 6 decimal places | ||
| // This is required by Kubernetes API which expects RFC3339Micro format | ||
|
|
||
| // Create a datetime with 5 digits of precision (962170 microseconds = .96217 seconds) | ||
| var dt = new DateTime(2025, 11, 17, 22, 52, 34, 962, DateTimeKind.Utc).AddTicks(1700); | ||
|
|
||
| var secret = new V1Secret | ||
| { | ||
| Metadata = new V1ObjectMeta | ||
| { | ||
| Name = "test-secret", | ||
| CreationTimestamp = dt, | ||
| }, | ||
| }; | ||
|
|
||
| var json = KubernetesJson.Serialize(secret); | ||
|
|
||
| // Verify the datetime is serialized with exactly 6 decimal places | ||
| Assert.Contains("2025-11-17T22:52:34.962170Z", json); | ||
|
|
||
| // Also verify it doesn't have 5 digits (which would fail in Kubernetes) | ||
| Assert.DoesNotContain("2025-11-17T22:52:34.96217Z", json); | ||
| } |
Copilot
AI
Nov 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test only covers one specific case with non-zero trailing digits. Consider adding a test case for fractional seconds with trailing zeros (e.g., 100000 microseconds = .100000 seconds) to ensure they are always formatted with exactly 6 decimal places, not trimmed to fewer digits like .1Z.
| if (ticks == 0) | ||
| { | ||
| // No fractional seconds - use format without fractional part | ||
| var basePart = date.ToString("yyyy-MM-dd'T'HH:mm:ss", CultureInfo.InvariantCulture); |
Copilot
AI
Nov 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] For consistency with the existing format strings (like RFC3339Format and RFC3339MicroFormat), consider using quoted separators: "yyyy'-'MM'-'dd'T'HH':'mm':'ss" instead of "yyyy-MM-dd'T'HH:mm:ss".
| var basePart = date.ToString("yyyy-MM-dd'T'HH:mm:ss", CultureInfo.InvariantCulture); | |
| var basePart = date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss", CultureInfo.InvariantCulture); |
…oseconds (#1687) * Initial plan * Fix datetime serialization to always output 6 decimal places for fractional seconds Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
* Initial plan * Add .NET 10 support to all projects and workflows Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> * Fix datetime serialization to always output 6 decimal places for microseconds (#1687) * Initial plan * Fix datetime serialization to always output 6 decimal places for fractional seconds Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> * Initial plan --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
…oseconds (#1687) * Initial plan * Fix datetime serialization to always output 6 decimal places for fractional seconds Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
* Initial plan * Add .NET 10 support to all projects and workflows Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> * Fix datetime serialization to always output 6 decimal places for microseconds (#1687) * Initial plan * Fix datetime serialization to always output 6 decimal places for fractional seconds Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tg123 <170430+tg123@users.noreply.github.com> * Initial plan --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tg123 <170430+tg123@users.noreply.github.com>
The Kubernetes API expects RFC3339Micro format with exactly 6 decimal places for fractional seconds. The existing serializer was trimming trailing zeros, producing timestamps like
2025-11-17T22:52:34.96217Z(5 digits) instead of2025-11-17T22:52:34.962170Z(6 digits), causingBadRequesterrors.Changes
KubernetesDateTimeOffsetConverter.Write: Check for fractional seconds via ticks; when present, use
RFC3339MicroFormat(6 digits); when absent, omit fractional part entirely for backward compatibilityKubernetesJsonTests: Add test verifying 6-digit serialization for fractional seconds
Fixes the
DatetimeFieldTeste2e test failure when creating Kubernetes Event objects withDateTime.Now.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
crl.comodoca.com/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/csharp/csharp/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj --packages /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot(dns block)idp.issuer.url/usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net9.0/KubernetesClient.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net9.0/KubernetesClient.Tests.deps.json /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net9.0/testhost.dll --port 46159 --endpoint 127.0.0.1:046159 --role client --parentprocessid 8889 --telemetryoptedin false(dns block)/usr/share/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net8.0/KubernetesClient.Tests.runtimeconfig.json --depsfile /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net8.0/KubernetesClient.Tests.deps.json /home/REDACTED/work/csharp/csharp/tests/KubernetesClient.Tests/bin/Debug/net8.0/testhost.dll --port 35773 --endpoint 127.0.0.1:035773 --role client --parentprocessid 8882 --telemetryoptedin false(dns block)ocsp.comodoca.com/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/.dotnet/dotnet restore --no-dependencies /home/REDACTED/work/csharp/csharp/src/KubernetesClient.Classic/KubernetesClient.Classic.csproj --packages /home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/csharp/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.