Skip to content

Commit c0d22d1

Browse files
github-actions[bot]Copilotdsyme
authored
Fix #1437: ConvertDateTimeOffset falls back to AsDateTime for timezone-less xs:dateTime values (#1617)
xs:dateTime values without a timezone suffix (e.g. '2022-04-28T10:09:17') are parsed by ParseISO8601FormattedDateTime as DateTimeKind.Unspecified. AsDateTimeOffset rejects these (returning None) to keep inference strict, causing a runtime exception when the XSD declares the field as xs:dateTime. Fix: In TextRuntime.ConvertDateTimeOffset, fall back to AsDateTime when AsDateTimeOffset returns None. AsDateTime already converts Unspecified to Local, so DateTimeOffset(dt) uses the local timezone offset — matching standard xs:dateTime semantics for timezone-free values. Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Don Syme <dsyme@users.noreply.github.com>
1 parent 5e47def commit c0d22d1

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

src/FSharp.Data.Runtime.Utilities/TextRuntime.fs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,16 @@ type TextRuntime =
7171
|> Option.bind (TextConversions.AsDateTime(TextRuntime.GetCulture cultureStr))
7272

7373
static member ConvertDateTimeOffset(cultureStr, text) =
74+
let culture = TextRuntime.GetCulture cultureStr
75+
7476
text
75-
|> Option.bind (TextConversions.AsDateTimeOffset(TextRuntime.GetCulture cultureStr))
77+
|> Option.bind (fun s ->
78+
match TextConversions.AsDateTimeOffset culture s with
79+
| Some dto -> Some dto
80+
| None ->
81+
// Fall back for xs:dateTime values without timezone (DateTimeKind.Unspecified).
82+
// AsDateTime converts Unspecified to Local, so DateTimeOffset(dt) uses the local offset.
83+
TextConversions.AsDateTime culture s |> Option.map DateTimeOffset)
7684

7785
static member ConvertTimeSpan(cultureStr, text) =
7886
text

tests/FSharp.Data.Tests/XmlProvider.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,14 @@ let ``date is formatted properly``() =
12131213
validXml.XElement.Attribute(XName.Get "date").Value
12141214
|> should equal "2018-08-29"
12151215

1216+
[<Test>]
1217+
let ``xs:dateTime without timezone parses as DateTimeOffset (issue 1437)``() =
1218+
// xs:dateTime values without timezone offset (DateTimeKind.Unspecified) should
1219+
// still parse successfully as DateTimeOffset, treated as local time.
1220+
let xml = """<A int="0" long="0" date="2022-01-01" dateTime="2022-04-28T10:09:17" boolean="false" decimal="0" double="0" />"""
1221+
let a = SimpleTypes.Parse(xml)
1222+
a.DateTime.DateTime |> should equal (System.DateTime(2022, 4, 28, 10, 9, 17))
1223+
12161224
type TimeSpanXML = XmlProvider<"Data/TimeSpans.xml">
12171225

12181226
[<Test>]

0 commit comments

Comments
 (0)