Skip to content

Support ISO 8601 24:00:00 (endOfDayFrag) in XSD DateTime validation#124437

Open
Copilot wants to merge 4 commits intomainfrom
copilot/add-xml-validation-support
Open

Support ISO 8601 24:00:00 (endOfDayFrag) in XSD DateTime validation#124437
Copilot wants to merge 4 commits intomainfrom
copilot/add-xml-validation-support

Conversation

Copy link
Contributor

Copilot AI commented Feb 15, 2026

Description

Fixes #29005

XML Schema validation rejected 24:00:00 (endOfDayFrag) even though W3C XML Schema 1.1 Part 2 explicitly defines it as valid. PR #124142 added the underlying ISO 8601 24:00 support to DateTime/DateTimeOffset/TimeOnly parsing; this extends that support to the XSD layer used by XmlConvert and XML Schema validation.

Changes

  • XsdDateTime.ParseTime(): hour < 24hour <= 24, with post-parse validation rejecting hour=24 when minute, second, or fraction are non-zero
  • XsdDateTime.InitiateXsdDateTime()TryInitiateXsdDateTime(): When hour=24, sets hour=0 and adds one day. Returns false on overflow (e.g., 9999-12-31T24:00:00) instead of throwing
  • TryParse() / constructor: Updated to use TryInitiateXsdDateTime for exception-free overflow handling
  • 47 new test cases: Valid/invalid endOfDay across xs:dateTime, xs:time, XDR variants; schema validation end-to-end; leap year/year boundary transitions; fractional seconds; overflow; regression coverage for hours 0–23
// Previously threw FormatException; now parses correctly
var dt = XmlConvert.ToDateTime("2007-04-05T24:00:00", XmlDateTimeSerializationMode.RoundtripKind);
// dt == 2007-04-06T00:00:00 (next day's midnight, per spec)

// Schema validation now accepts endOfDayFrag
var settings = new XmlReaderSettings { ValidationType = ValidationType.Schema };
settings.Schemas.Add("ns", XmlReader.Create(new StringReader(xsd)));
using var reader = XmlReader.Create(new StringReader(xml), settings);
new XmlDocument().Load(reader); // no longer throws

Breaking change considerations

This is a relaxation — previously rejected inputs now parse successfully:

  • 2007-04-05T24:00:002007-04-06T00:00:00 (was FormatException)
  • 24:00:00 as xs:time → valid (was validation error)
  • 24:01:00, 24:00:01, 24:00:00.0000001 remain invalid
  • 9999-12-31T24:00:00 remains invalid (DateTime overflow)
  • Round-trip: serializing the parsed result produces 00:00:00 on the next day, not the original 24:00:00 input — consistent with ISO 8601 semantic equivalence

Code relying on FormatException for 24:00:00 inputs or on schema validation rejecting them will observe changed behavior.

Adjacent scope

All XSD types with time components share the same ParseTime() path: xs:dateTime, xs:time, and XDR datetime/time variants are all covered. Types without time components (xs:date, xs:gYear, etc.) are unaffected.

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:

  • bla
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing NDLY=Debug S_SAME_AS_TARGET/home/REDACTED/work/runtime/runtime/.dotnet/dotnet /home/REDACTED/wor/home/REDACTED/work/runtime/runtime/.dotnet/sdk/11.0.100-alpha.1.26064.118/MSBuild.dll ITS=64 DTARGET_64BIT -D/nologo (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing 8 SAME_AS_TARGET_Ouname /lib/x86_64-linu-s /usr/bin/../lib/gcc/x86_64-linux/usr/bin/clang&#43;&#43;-18 -DBUILDENV_DEBUG=1 -DCOMPILER_SUPPORTS_W_RESERVED_IDENTIFIER -DDEBUG -DDISABLE_CONTRACTS -DEXPORT_SHARED_API -DFALLBACK_OS_IS_SAME_AS_TARGET/home/REDACTED/work/runtime/runtime/.dotnet/dotnet -DTARGET_64BIT -DTARGET_AMD64 - (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing /bin/sh XPORT_SHARED_API/usr/bin/sh rity.Native -DHOST_UNIX /bin/sh (dns block)
  • foo
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing NDLY=Debug S_SAME_AS_TARGET/home/REDACTED/work/runtime/runtime/.dotnet/dotnet /home/REDACTED/wor/home/REDACTED/work/runtime/runtime/.dotnet/sdk/11.0.100-alpha.1.26064.118/MSBuild.dll ITS=64 DTARGET_64BIT -D/nologo (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing 8 SAME_AS_TARGET_Ouname /lib/x86_64-linu-s /usr/bin/../lib/gcc/x86_64-linux/usr/bin/clang&#43;&#43;-18 -DBUILDENV_DEBUG=1 -DCOMPILER_SUPPORTS_W_RESERVED_IDENTIFIER -DDEBUG -DDISABLE_CONTRACTS -DEXPORT_SHARED_API -DFALLBACK_OS_IS_SAME_AS_TARGET/home/REDACTED/work/runtime/runtime/.dotnet/dotnet -DTARGET_64BIT -DTARGET_AMD64 - (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing /bin/sh XPORT_SHARED_API/usr/bin/sh rity.Native -DHOST_UNIX /bin/sh (dns block)
  • notfound.invalid.corp.microsoft.com
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing NDLY=Debug S_SAME_AS_TARGET/home/REDACTED/work/runtime/runtime/.dotnet/dotnet /home/REDACTED/wor/home/REDACTED/work/runtime/runtime/.dotnet/sdk/11.0.100-alpha.1.26064.118/MSBuild.dll ITS=64 DTARGET_64BIT -D/nologo (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing 8 SAME_AS_TARGET_Ouname /lib/x86_64-linu-s /usr/bin/../lib/gcc/x86_64-linux/usr/bin/clang&#43;&#43;-18 -DBUILDENV_DEBUG=1 -DCOMPILER_SUPPORTS_W_RESERVED_IDENTIFIER -DDEBUG -DDISABLE_CONTRACTS -DEXPORT_SHARED_API -DFALLBACK_OS_IS_SAME_AS_TARGET/home/REDACTED/work/runtime/runtime/.dotnet/dotnet -DTARGET_64BIT -DTARGET_AMD64 - (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing /bin/sh XPORT_SHARED_API/usr/bin/sh rity.Native -DHOST_UNIX /bin/sh (dns block)
  • test.test
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing NDLY=Debug S_SAME_AS_TARGET/home/REDACTED/work/runtime/runtime/.dotnet/dotnet /home/REDACTED/wor/home/REDACTED/work/runtime/runtime/.dotnet/sdk/11.0.100-alpha.1.26064.118/MSBuild.dll ITS=64 DTARGET_64BIT -D/nologo (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing 8 SAME_AS_TARGET_Ouname /lib/x86_64-linu-s /usr/bin/../lib/gcc/x86_64-linux/usr/bin/clang&#43;&#43;-18 -DBUILDENV_DEBUG=1 -DCOMPILER_SUPPORTS_W_RESERVED_IDENTIFIER -DDEBUG -DDISABLE_CONTRACTS -DEXPORT_SHARED_API -DFALLBACK_OS_IS_SAME_AS_TARGET/home/REDACTED/work/runtime/runtime/.dotnet/dotnet -DTARGET_64BIT -DTARGET_AMD64 - (dns block)
    • Triggering command: /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet /home/REDACTED/work/runtime/runtime/artifacts/bin/testhost/net11.0-linux-Debug-x64/dotnet exec --runtimeconfig System.Private.Xml.Tests.runtimeconfig.json --depsfile System.Private.Xml.Tests.deps.json /home/REDACTED/.nuget/packages/microsoft.dotnet.xunitconsoleREDACTED/2.9.3-beta.26069.103/build/../tools/net/xunit.console.dll System.Private.Xml.Tests.dll -xml testResults.xml -nologo -notrait category=OuterLoop -notrait category=failing /bin/sh XPORT_SHARED_API/usr/bin/sh rity.Native -DHOST_UNIX /bin/sh (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits February 15, 2026 02:14
Co-authored-by: jeffhandley <1031940+jeffhandley@users.noreply.github.com>
…eTime

Co-authored-by: jeffhandley <1031940+jeffhandley@users.noreply.github.com>
Co-authored-by: jeffhandley <1031940+jeffhandley@users.noreply.github.com>
@github-actions github-actions bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Feb 15, 2026
Copilot AI changed the title [WIP] Implement XML validation support for endOfDayFlag Support ISO 8601 24:00:00 (endOfDayFrag) in XSD DateTime validation Feb 15, 2026
Copilot AI requested a review from jeffhandley February 15, 2026 02:29
@jeffhandley jeffhandley added area-System.Xml and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Feb 15, 2026
@jeffhandley jeffhandley marked this pull request as ready for review February 15, 2026 02:51
Copilot AI review requested due to automatic review settings February 15, 2026 02:51
@jeffhandley jeffhandley requested review from tarekgh and removed request for Copilot February 15, 2026 02:52
@jeffhandley
Copy link
Member

@tarekgh Tagged you for review next week. Not urgent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

XML validation doesn't support endOfDayFrag (24:00:00)

2 participants