From d6a29d58155ff67c8ee50da1d49f567a1542326f Mon Sep 17 00:00:00 2001 From: Mangel Maxime Date: Mon, 26 Oct 2026 21:25:31 +0100 Subject: [PATCH] fix(python/beam/rust): implicit DateTime to DateTimeOffset --- src/Fable.Transforms/Beam/Replacements.fs | 3 +++ src/Fable.Transforms/Python/Replacements.fs | 3 +++ src/Fable.Transforms/Rust/Replacements.fs | 1 + tests/Beam/DateTimeOffsetTests.fs | 13 +++++++++++++ tests/Python/TestDateTimeOffset.fs | 13 +++++++++++++ tests/Rust/tests/src/DateTimeOffsetTests.fs | 13 +++++++++++++ 6 files changed, 46 insertions(+) diff --git a/src/Fable.Transforms/Beam/Replacements.fs b/src/Fable.Transforms/Beam/Replacements.fs index 4b3df7f340..22d086f994 100644 --- a/src/Fable.Transforms/Beam/Replacements.fs +++ b/src/Fable.Transforms/Beam/Replacements.fs @@ -5036,6 +5036,9 @@ let private dateTimeOffsets (args: Expr list) = match info.CompiledName with + | "op_Implicit" -> + Helper.LibCall(com, "fable_date_offset", "from_date", t, args @ [ makeIntConst 0 ], ?loc = r) + |> Some | ".ctor" -> match args with | [] -> Helper.LibCall(com, "fable_date_offset", "min_value", t, [], ?loc = r) |> Some diff --git a/src/Fable.Transforms/Python/Replacements.fs b/src/Fable.Transforms/Python/Replacements.fs index 248e3266ef..3c8095f08f 100644 --- a/src/Fable.Transforms/Python/Replacements.fs +++ b/src/Fable.Transforms/Python/Replacements.fs @@ -3191,6 +3191,9 @@ let dates (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr optio "DateOffset" match i.CompiledName with + | "op_Implicit" -> + Helper.LibCall(com, "DateOffset", "fromDate", t, args, i.SignatureArgTypes, ?loc = r) + |> Some | ".ctor" -> match args with | [] -> Helper.LibCall(com, moduleName, "minValue", t, [], [], ?loc = r) |> Some diff --git a/src/Fable.Transforms/Rust/Replacements.fs b/src/Fable.Transforms/Rust/Replacements.fs index 91add9cd16..f02f077db3 100644 --- a/src/Fable.Transforms/Rust/Replacements.fs +++ b/src/Fable.Transforms/Rust/Replacements.fs @@ -2652,6 +2652,7 @@ let dateTimeOffsets (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: _offset ] -> "new_ymdhms_micro" |> Some | _ -> None |> Option.map (fun meth -> makeStaticMemberCall com r t i "DateTimeOffset" meth args) + | "op_Implicit", _ -> makeStaticMemberCall com r t i "DateTimeOffset" "new_datetime" args |> Some | ("Compare" | "CompareTo" | "Equals" | "GetHashCode"), thisArg -> valueTypes com ctx r t i thisArg args | "Add", Some c -> Operation(Binary(BinaryOperator.BinaryPlus, c, args.Head), Tags.empty, t, r) diff --git a/tests/Beam/DateTimeOffsetTests.fs b/tests/Beam/DateTimeOffsetTests.fs index 64eb006b15..e791c81ca9 100644 --- a/tests/Beam/DateTimeOffsetTests.fs +++ b/tests/Beam/DateTimeOffsetTests.fs @@ -518,3 +518,16 @@ let ``test DateTimeOffset constructor from DateOnly and TimeOnly works`` () = dt.Minute |> equal dt_exp.Minute dt.Second |> equal dt_exp.Second dt.Millisecond |> equal dt_exp.Millisecond + +[] +let ``test Implicit conversion from DateTime preserves value`` () = + let d = DateTime(2024, 1, 15, 13, 23, 30, DateTimeKind.Utc) + let dto: DateTimeOffset = d + dto |> equal (DateTimeOffset(d)) + dto.Offset |> equal TimeSpan.Zero + dto.Year |> equal 2024 + dto.Month |> equal 1 + dto.Day |> equal 15 + dto.Hour |> equal 13 + dto.Minute |> equal 23 + dto.Second |> equal 30 diff --git a/tests/Python/TestDateTimeOffset.fs b/tests/Python/TestDateTimeOffset.fs index c4ea6ac15c..af806354cc 100644 --- a/tests/Python/TestDateTimeOffset.fs +++ b/tests/Python/TestDateTimeOffset.fs @@ -569,3 +569,16 @@ let ``test DateTimeOffset constructor from DateOnly and TimeOnly works`` () = dt.Minute |> equal dt_exp.Minute dt.Second |> equal dt_exp.Second dt.Millisecond |> equal dt_exp.Millisecond + +[] +let ``test Implicit conversion from DateTime preserves value`` () = + let d = DateTime(2024, 1, 15, 13, 23, 30, DateTimeKind.Utc) + let dto: DateTimeOffset = d + dto |> equal (DateTimeOffset(d)) + dto.Offset |> equal TimeSpan.Zero + dto.UtcDateTime.Year |> equal 2024 + dto.UtcDateTime.Month |> equal 1 + dto.UtcDateTime.Day |> equal 15 + dto.UtcDateTime.Hour |> equal 13 + dto.UtcDateTime.Minute |> equal 23 + dto.UtcDateTime.Second |> equal 30 diff --git a/tests/Rust/tests/src/DateTimeOffsetTests.fs b/tests/Rust/tests/src/DateTimeOffsetTests.fs index e0f13dd684..d95c8c5b67 100644 --- a/tests/Rust/tests/src/DateTimeOffsetTests.fs +++ b/tests/Rust/tests/src/DateTimeOffsetTests.fs @@ -1031,3 +1031,16 @@ let ``-10s offset throws exception`` () = let source = DateTimeOffset(2007, 9, 1, 14, 30, 0, TimeSpan.Zero) (fun () -> source.ToOffset(TimeSpan(0, 0, -10))) |> throwsErrorContaining "Offset must be specified in whole minutes" + +[] +let ``Implicit conversion from DateTime preserves value`` () = + let d = DateTime(2024, 1, 15, 13, 23, 30, DateTimeKind.Utc) + let dto: DateTimeOffset = d + dto |> equal (DateTimeOffset(d)) + dto.Offset |> equal TimeSpan.Zero + dto.Year |> equal 2024 + dto.Month |> equal 1 + dto.Day |> equal 15 + dto.Hour |> equal 13 + dto.Minute |> equal 23 + dto.Second |> equal 30