diff --git a/src/embed_tests/TestConverter.cs b/src/embed_tests/TestConverter.cs index 9acfbe42d..3d68456e3 100644 --- a/src/embed_tests/TestConverter.cs +++ b/src/embed_tests/TestConverter.cs @@ -187,6 +187,53 @@ public void ConvertDateTimeRoundTrip(DateTimeKind kind) Assert.AreEqual(datetime, result); } + [TestCase("")] + [TestCase("America/New_York")] + [TestCase("UTC")] + public void ConvertDateTimeWithTimeZonePythonToCSharp(string timeZone) + { + const int year = 2024; + const int month = 2; + const int day = 27; + const int hour = 12; + const int minute = 30; + const int second = 45; + + using (Py.GIL()) + { + dynamic module = PyModule.FromString("module", @$" +from clr import AddReference +AddReference(""Python.EmbeddingTest"") +AddReference(""System"") + +from Python.EmbeddingTest import * + +from datetime import datetime +from pytz import timezone + +tzinfo = timezone('{timeZone}') if '{timeZone}' else None + +def GetPyDateTime(): + return datetime({year}, {month}, {day}, {hour}, {minute}, {second}, tzinfo=tzinfo) \ + if tzinfo else \ + datetime({year}, {month}, {day}, {hour}, {minute}, {second}) + +def GetNextDay(dateTime): + return TestConverter.GetNextDay(dateTime) +"); + + var pyDateTime = module.GetPyDateTime(); + var dateTimeResult = default(object); + + Assert.DoesNotThrow(() => Converter.ToManaged(pyDateTime, typeof(DateTime), out dateTimeResult, false)); + + var managedDateTime = (DateTime)dateTimeResult; + + var expectedDateTime = new DateTime(year, month, day, hour, minute, second); + Assert.AreEqual(expectedDateTime, managedDateTime); + } + } + [Test] public void ConvertTimestampRoundTrip() { @@ -362,7 +409,7 @@ class PyGetListImpl(test.GetListImpl): List result = inst.GetList(); CollectionAssert.AreEqual(new[] { "testing" }, result); } - + [Test] public void PrimitiveIntConversion() { diff --git a/src/perf_tests/Python.PerformanceTests.csproj b/src/perf_tests/Python.PerformanceTests.csproj index d081af07c..373383145 100644 --- a/src/perf_tests/Python.PerformanceTests.csproj +++ b/src/perf_tests/Python.PerformanceTests.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + compile @@ -25,7 +25,7 @@ - + diff --git a/src/runtime/Converter.cs b/src/runtime/Converter.cs index 05afe2f38..3f249f0aa 100644 --- a/src/runtime/Converter.cs +++ b/src/runtime/Converter.cs @@ -76,7 +76,6 @@ static Converter() timeSpanCtor = Runtime.PyObject_GetAttrString(dateTimeMod.Borrow(), "timedelta").MoveToPyObject(); PythonException.ThrowIfIsNull(timeSpanCtor); - tzInfoCtor = new Lazy(() => { var tzInfoMod = PyModule.FromString("custom_tzinfo", @" @@ -1124,20 +1123,6 @@ internal static bool ToPrimitive(BorrowedReference value, Type obType, out objec var minute = Runtime.PyObject_GetAttrString(value, minutePtr); var second = Runtime.PyObject_GetAttrString(value, secondPtr); var microsecond = Runtime.PyObject_GetAttrString(value, microsecondPtr); - var timeKind = DateTimeKind.Unspecified; - var tzinfo = Runtime.PyObject_GetAttrString(value, tzinfoPtr); - - NewReference hours = default; - NewReference minutes = default; - if (!tzinfo.IsNone() && !tzinfo.IsNull()) - { - hours = Runtime.PyObject_GetAttrString(tzinfo.Borrow(), hoursPtr); - minutes = Runtime.PyObject_GetAttrString(tzinfo.Borrow(), minutesPtr); - if (Runtime.PyLong_AsLong(hours.Borrow()) == 0 && Runtime.PyLong_AsLong(minutes.Borrow()) == 0) - { - timeKind = DateTimeKind.Utc; - } - } var convertedHour = 0L; var convertedMinute = 0L; @@ -1158,8 +1143,7 @@ internal static bool ToPrimitive(BorrowedReference value, Type obType, out objec (int)convertedHour, (int)convertedMinute, (int)convertedSecond, - millisecond: (int)milliseconds, - timeKind); + (int)milliseconds); year.Dispose(); month.Dispose(); @@ -1169,16 +1153,6 @@ internal static bool ToPrimitive(BorrowedReference value, Type obType, out objec second.Dispose(); microsecond.Dispose(); - if (!tzinfo.IsNull()) - { - tzinfo.Dispose(); - if (!tzinfo.IsNone()) - { - hours.Dispose(); - minutes.Dispose(); - } - } - Exceptions.Clear(); return true; default: diff --git a/src/runtime/Properties/AssemblyInfo.cs b/src/runtime/Properties/AssemblyInfo.cs index 2f4055fed..a77e40b7a 100644 --- a/src/runtime/Properties/AssemblyInfo.cs +++ b/src/runtime/Properties/AssemblyInfo.cs @@ -4,5 +4,5 @@ [assembly: InternalsVisibleTo("Python.EmbeddingTest, PublicKey=00240000048000009400000006020000002400005253413100040000110000005ffd8f49fb44ab0641b3fd8d55e749f716e6dd901032295db641eb98ee46063cbe0d4a1d121ef0bc2af95f8a7438d7a80a3531316e6b75c2dae92fb05a99f03bf7e0c03980e1c3cfb74ba690aca2f3339ef329313bcc5dccced125a4ffdc4531dcef914602cd5878dc5fbb4d4c73ddfbc133f840231343e013762884d6143189")] [assembly: InternalsVisibleTo("Python.Test, PublicKey=00240000048000009400000006020000002400005253413100040000110000005ffd8f49fb44ab0641b3fd8d55e749f716e6dd901032295db641eb98ee46063cbe0d4a1d121ef0bc2af95f8a7438d7a80a3531316e6b75c2dae92fb05a99f03bf7e0c03980e1c3cfb74ba690aca2f3339ef329313bcc5dccced125a4ffdc4531dcef914602cd5878dc5fbb4d4c73ddfbc133f840231343e013762884d6143189")] -[assembly: AssemblyVersion("2.0.26")] -[assembly: AssemblyFileVersion("2.0.26")] +[assembly: AssemblyVersion("2.0.27")] +[assembly: AssemblyFileVersion("2.0.27")] diff --git a/src/runtime/Python.Runtime.csproj b/src/runtime/Python.Runtime.csproj index 0463bb748..25f01f3cb 100644 --- a/src/runtime/Python.Runtime.csproj +++ b/src/runtime/Python.Runtime.csproj @@ -5,7 +5,7 @@ Python.Runtime Python.Runtime QuantConnect.pythonnet - 2.0.26 + 2.0.27 false LICENSE https://github.com/pythonnet/pythonnet