diff --git a/engines/ARIEC61850.lock.json b/engines/ARIEC61850.lock.json index 095525e0e..9d631dc08 100644 --- a/engines/ARIEC61850.lock.json +++ b/engines/ARIEC61850.lock.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "repository": "masarray/ARIEC61850", "ref": "main", - "commit": "902fc828dcf976a705dc73b88f1e9c42e5bf6a93", - "sourcePullRequest": 54, + "commit": "8b46cfed0614a4d0b0a5bf73fa7a6e77cf6fe817", + "sourcePullRequest": 55, "purpose": "Immutable ARIEC61850 revision for ARSAS CI, tests, packaging, diagnostics, and release provenance." } diff --git a/tests/ARSAS.Tests/Iec61850EngineTimestampIntegrationTests.cs b/tests/ARSAS.Tests/Iec61850EngineTimestampIntegrationTests.cs new file mode 100644 index 000000000..08b624471 --- /dev/null +++ b/tests/ARSAS.Tests/Iec61850EngineTimestampIntegrationTests.cs @@ -0,0 +1,44 @@ +using System.Buffers.Binary; +using System.Globalization; +using AR.Iec61850.Binding; +using AR.Iec61850.Mms; +using ArIED61850Tester; + +namespace ARSAS.Tests; + +public sealed class Iec61850EngineTimestampIntegrationTests +{ + [Fact] + public void PinnedEngine_Preserves_2006000_Fraction_And_Arsas_Rounds_It_To_201ms() + { + var seconds = new DateTimeOffset(2026, 8, 13, 10, 0, 31, TimeSpan.Zero).ToUnixTimeSeconds(); + Span bytes = stackalloc byte[8]; + BinaryPrimitives.WriteUInt32BigEndian(bytes[..4], checked((uint)seconds)); + + // IEC 61850 fractional-second bytes from the engine regression case: + // 0x335A86 / 2^24 = 0.200600028... s -> 31.2006000 at .NET tick resolution. + bytes[4] = 0x33; + bytes[5] = 0x5A; + bytes[6] = 0x86; + bytes[7] = 0x00; + + var utc = Iec61850UtcTime.FromBytes(bytes); + var decoded = Iec61850TimestampDecoder.Decode(MmsDataValue.UtcTime(utc)); + + Assert.True(decoded.IsDecoded); + Assert.True(decoded.DisplayTime.EndsWith("31.2006000", StringComparison.Ordinal), decoded.DisplayTime); + + Assert.True( + DateTime.TryParseExact( + decoded.DisplayTime, + "yyyy-MM-dd HH:mm:ss.fffffff", + CultureInfo.InvariantCulture, + DateTimeStyles.None, + out var parsed), + decoded.DisplayTime); + + Assert.Equal( + "31.201", + Iec61850TimestampPresentation.FormatMilliseconds(parsed, "ss.fff")); + } +}