Skip to content

Commit 2c87048

Browse files
committed
Fix packaged Fable date parsing
1 parent af91b5b commit 2c87048

4 files changed

Lines changed: 39 additions & 15 deletions

File tree

scripts/check-fable-package-compat.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ cd "$repo_root"
1111
rm -rf "$out_dir" "$package_cache"
1212
dotnet pack src/CodecMapper/CodecMapper.fsproj --nologo -v minimal
1313
dotnet tool run fable -- tests/CodecMapper.FablePackageTests -o "$out_dir" --noRestore --silent
14+
node "$out_dir/Program.js"

scripts/check-fable5-package-compat.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ dotnet tool install fable --version 5.0.0-rc.2 --tool-path "$tool_dir"
1616

1717
DOTNET_ROOT="$dotnet_root" PATH="$dotnet_root:$PATH" \
1818
"$tool_dir/fable" tests/CodecMapper.FablePackageTests -o "$out_dir" --noRestore --silent
19+
node "$out_dir/Program.js"

src/CodecMapper/Core.fs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,40 @@ module Core =
148148
let tryParseFloatInvariant = tryParseFloatPlatformInvariant
149149
let tryParseDecimalInvariant = tryParseDecimalPlatformInvariant
150150

151+
///
152+
/// Fable's packaged `fable-library-js` surface does not currently expose the
153+
/// `ParseExact` helpers for date/time types, so the shared schemas need one
154+
/// portable entry point that preserves exact parsing on .NET and compatible
155+
/// parsing on Fable.
156+
let parseDateTimeRoundtripInvariant (text: string) =
157+
#if FABLE_COMPILER
158+
System.DateTime.Parse(text)
159+
#else
160+
System.DateTime.ParseExact(text, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind)
161+
#endif
162+
163+
///
164+
/// The package consumer path exercises the published Fable runtime rather
165+
/// than the local source build, so `DateTimeOffset` parsing needs the same
166+
/// fallback to avoid importing helpers that the package does not ship.
167+
let parseDateTimeOffsetRoundtripInvariant (text: string) =
168+
#if FABLE_COMPILER
169+
System.DateTimeOffset.Parse(text)
170+
#else
171+
System.DateTimeOffset.ParseExact(text, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind)
172+
#endif
173+
174+
///
175+
/// `TimeSpan.ParseExact` hits the same missing-helper problem under Fable,
176+
/// while plain invariant parsing still accepts the canonical `"c"` payloads
177+
/// that the encoder emits.
178+
let parseTimeSpanConstantInvariant (text: string) =
179+
#if FABLE_COMPILER
180+
System.TimeSpan.Parse(text)
181+
#else
182+
System.TimeSpan.ParseExact(text, "c", CultureInfo.InvariantCulture)
183+
#endif
184+
151185
let private failIntegerToken typeName allowMinus token =
152186
match classifyIntegerToken allowMinus token with
153187
| OutOfRangeToken -> failwithf "%s value out of range: %s" typeName token

src/CodecMapper/Schema.fs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -235,29 +235,17 @@ module Schema =
235235
/// A schema for `DateTime` using the round-trippable `"O"` string format.
236236
let dateTime: Schema<System.DateTime> =
237237
string
238-
|> map
239-
(fun value ->
240-
System.DateTime.ParseExact(value, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind))
241-
(fun value -> value.ToString("O", CultureInfo.InvariantCulture))
238+
|> map parseDateTimeRoundtripInvariant (fun value -> value.ToString("O", CultureInfo.InvariantCulture))
242239

243240
/// A schema for `DateTimeOffset` using the round-trippable `"O"` string format.
244241
let dateTimeOffset: Schema<System.DateTimeOffset> =
245242
string
246-
|> map
247-
(fun value ->
248-
System.DateTimeOffset.ParseExact(
249-
value,
250-
"O",
251-
CultureInfo.InvariantCulture,
252-
DateTimeStyles.RoundtripKind
253-
))
254-
(fun value -> value.ToString("O", CultureInfo.InvariantCulture))
243+
|> map parseDateTimeOffsetRoundtripInvariant (fun value -> value.ToString("O", CultureInfo.InvariantCulture))
255244

256245
/// A schema for `TimeSpan` using the invariant `"c"` format.
257246
let timeSpan: Schema<System.TimeSpan> =
258247
string
259-
|> map (fun value -> System.TimeSpan.ParseExact(value, "c", CultureInfo.InvariantCulture)) (fun value ->
260-
value.ToString("c", CultureInfo.InvariantCulture))
248+
|> map parseTimeSpanConstantInvariant (fun value -> value.ToString("c", CultureInfo.InvariantCulture))
261249

262250
///
263251
/// Keep the .NET path using round-trip float formatting, but let Fable use

0 commit comments

Comments
 (0)