diff --git a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiDate.cs b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiDate.cs index b35acdfe..5167e28c 100644 --- a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiDate.cs +++ b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiDate.cs @@ -106,7 +106,7 @@ private DateOnly GetFromBinary(long value) case eTargetProjectPlatform.SIMATICAX: var valAx = value / 100; - return valAx.AdjustForLeapDate(); + return valAx.GetDateOnly(); default: var valdef = value / 100; diff --git a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiDateTime.cs b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiDateTime.cs index 654cd69f..c2a8c1ad 100644 --- a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiDateTime.cs +++ b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiDateTime.cs @@ -138,7 +138,7 @@ private DateTime GetFromBinary(string value) private DateTime GetFromBinary(long val) { var dt = val / 100; - return dt.AdjustForLeapDateTime(); // DateTime.FromBinary(dt).AddYears(1969); + return dt.ToUtcDateTime(); // DateTime.FromBinary(dt).AddYears(1969); } private string GetFromDate(DateTime dateTime) diff --git a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiLDate.cs b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiLDate.cs index a0d8a422..7764ab6f 100644 --- a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiLDate.cs +++ b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiLDate.cs @@ -84,7 +84,7 @@ private DateOnly GetFromBinary(string value) private DateOnly GetFromBinary(long value) { var val = value / 100; - return val.AdjustForLeapDate(); // DateOnly.FromDateTime(DateTime.FromBinary(val).AddYears(1969)); + return val.GetDateOnly(); // DateOnly.FromDateTime(DateTime.FromBinary(val).AddYears(1969)); } private string GetFromDate(DateOnly date) diff --git a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiLDateTime.cs b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiLDateTime.cs index 748fe241..025c6620 100644 --- a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiLDateTime.cs +++ b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/BuiltInWrappers/WebApiLDateTime.cs @@ -84,7 +84,7 @@ private DateTime GetFromBinary(string value) private DateTime GetFromBinary(long val) { var dt = val / 100; - return dt.AdjustForLeapDateTime(); // DateTime.FromBinary(dt).AddYears(1969); + return dt.ToUtcDateTime(); // DateTime.FromBinary(dt).AddYears(1969); } diff --git a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/WebApiConnectorExtensions.cs b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/WebApiConnectorExtensions.cs index 4790cc3b..dea8d2f2 100644 --- a/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/WebApiConnectorExtensions.cs +++ b/src/AXSharp.connectors/src/AXSharp.Connector.S71500.WebAPI/WebApiConnectorExtensions.cs @@ -57,17 +57,19 @@ public static ConnectorAdapter CreateWebApi(this ConnectorAdapterBuilder adapter { Parameters = new object[] { ipAddress, userName, password, customServerCertHandler, ignoreSslErrors, platform, dbName } }; } - public static DateOnly AdjustForLeapDate(this long value) - { - var noLeap = DateOnly.FromDateTime(DateTime.FromBinary(value).AddYears(1969)); - var leapDays = DateTime.IsLeapYear(noLeap.Year) && ((noLeap.Month == 2 && noLeap.Day == 29) || noLeap.Month >= 3) ? -1 : 0; - return noLeap.AddDays(leapDays); + public static DateOnly GetDateOnly(this long value) + { + // 1 tick = 100 ns + // Use DateTimeKind.Utc for correct interpretation + var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) + .AddTicks(value); + + // Return the date portion in UTC + return DateOnly.FromDateTime(dateTime.ToUniversalTime()); } - public static DateTime AdjustForLeapDateTime(this long value) + public static DateTime ToUtcDateTime(this long value) { - var noLeap = DateTime.FromBinary(value).AddYears(1969); - var leapDays = DateTime.IsLeapYear(noLeap.Year) && ((noLeap.Month == 2 && noLeap.Day == 29) || noLeap.Month >= 3) ? -1 : 0; - return noLeap.AddDays(leapDays); + return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(value); } } \ No newline at end of file diff --git a/src/AXSharp.connectors/tests/AXSharp.Connector.Sax.WebAPITests/WebApiConnector/WebApiPrimitiveTests.cs b/src/AXSharp.connectors/tests/AXSharp.Connector.Sax.WebAPITests/WebApiConnector/WebApiPrimitiveTests.cs index 867f5e81..24042f36 100644 --- a/src/AXSharp.connectors/tests/AXSharp.Connector.Sax.WebAPITests/WebApiConnector/WebApiPrimitiveTests.cs +++ b/src/AXSharp.connectors/tests/AXSharp.Connector.Sax.WebAPITests/WebApiConnector/WebApiPrimitiveTests.cs @@ -186,8 +186,8 @@ public WebApiDateTests(ITestOutputHelper output) : base(output) [Fact] public virtual async void should_synchron_write_leap_value_check_leap() { - var testDate = new DateOnly(2025, 1, 1); - for (int i = 0; i < 100; i++) + var testDate = new DateOnly(2024, 1, 1); + for (int i = 0; i < 365*5; i++) { testDate = testDate.AddDays(1); TestConnector.TestApiConnector.ClearPeriodicReadSet(); @@ -195,7 +195,7 @@ public virtual async void should_synchron_write_leap_value_check_leap() var actual = await webApiPrimitive.GetAsync(); if(testDate != actual) Output.WriteLine($"Expected: {testDate} - Actual: {actual} {testDate == actual}"); - // Assert.Equal(testDate, actual); + Assert.Equal(testDate, actual); } } diff --git a/src/AXSharp.connectors/tests/ax-test-project/ax-test-project.sln b/src/AXSharp.connectors/tests/ax-test-project/ax-test-project.sln new file mode 100644 index 00000000..058b9016 --- /dev/null +++ b/src/AXSharp.connectors/tests/ax-test-project/ax-test-project.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ax_test_project", "ix\ax_test_project.csproj", "{C821E27A-DD87-A1A7-0B15-842E89FDA2A2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C821E27A-DD87-A1A7-0B15-842E89FDA2A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C821E27A-DD87-A1A7-0B15-842E89FDA2A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C821E27A-DD87-A1A7-0B15-842E89FDA2A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C821E27A-DD87-A1A7-0B15-842E89FDA2A2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {550C4796-5273-4560-BB73-CED0252EDF8C} + EndGlobalSection +EndGlobal