diff --git a/src/FSharp.Data.Runtime.Utilities/TextRuntime.fs b/src/FSharp.Data.Runtime.Utilities/TextRuntime.fs index f6d860dc8..f248981fd 100644 --- a/src/FSharp.Data.Runtime.Utilities/TextRuntime.fs +++ b/src/FSharp.Data.Runtime.Utilities/TextRuntime.fs @@ -71,8 +71,16 @@ type TextRuntime = |> Option.bind (TextConversions.AsDateTime(TextRuntime.GetCulture cultureStr)) static member ConvertDateTimeOffset(cultureStr, text) = + let culture = TextRuntime.GetCulture cultureStr + text - |> Option.bind (TextConversions.AsDateTimeOffset(TextRuntime.GetCulture cultureStr)) + |> Option.bind (fun s -> + match TextConversions.AsDateTimeOffset culture s with + | Some dto -> Some dto + | None -> + // Fall back for xs:dateTime values without timezone (DateTimeKind.Unspecified). + // AsDateTime converts Unspecified to Local, so DateTimeOffset(dt) uses the local offset. + TextConversions.AsDateTime culture s |> Option.map DateTimeOffset) static member ConvertTimeSpan(cultureStr, text) = text diff --git a/tests/FSharp.Data.Tests/XmlProvider.fs b/tests/FSharp.Data.Tests/XmlProvider.fs index 7e34da43a..e4f538d9d 100644 --- a/tests/FSharp.Data.Tests/XmlProvider.fs +++ b/tests/FSharp.Data.Tests/XmlProvider.fs @@ -1213,6 +1213,14 @@ let ``date is formatted properly``() = validXml.XElement.Attribute(XName.Get "date").Value |> should equal "2018-08-29" +[] +let ``xs:dateTime without timezone parses as DateTimeOffset (issue 1437)``() = + // xs:dateTime values without timezone offset (DateTimeKind.Unspecified) should + // still parse successfully as DateTimeOffset, treated as local time. + let xml = """""" + let a = SimpleTypes.Parse(xml) + a.DateTime.DateTime |> should equal (System.DateTime(2022, 4, 28, 10, 9, 17)) + type TimeSpanXML = XmlProvider<"Data/TimeSpans.xml"> []