feat(twincat): TIME/TOD as Double ms, DATE/DT as UTC DateTime with read decode + write encode (#306)

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 14:24:12 -04:00
parent d898262c4a
commit 90e3fe1cf7
10 changed files with 226 additions and 32 deletions
@@ -73,15 +73,28 @@ internal static class TwinCATArrayCodec
for (var i = 0; i < n; i++) a[i] = BinaryPrimitives.ReadInt32LittleEndian(bytes[(i * stride)..]);
return a;
}
case TwinCATDataType.UDInt or TwinCATDataType.Time or TwinCATDataType.Date
or TwinCATDataType.DateTime or TwinCATDataType.TimeOfDay:
case TwinCATDataType.UDInt:
{
// TIME / DATE / DT / TOD publish their raw 32-bit count — the same CLR shape (uint) a
// scalar of those types publishes.
var a = new uint[n];
for (var i = 0; i < n; i++) a[i] = BinaryPrimitives.ReadUInt32LittleEndian(bytes[(i * stride)..]);
return a;
}
case TwinCATDataType.Time or TwinCATDataType.TimeOfDay:
{
// TIME / TOD publish milliseconds as double — the same CLR shape a scalar publishes (#306).
var a = new double[n];
for (var i = 0; i < n; i++)
a[i] = (double)TwinCATTemporalCodec.Decode(declared, BinaryPrimitives.ReadUInt32LittleEndian(bytes[(i * stride)..]));
return a;
}
case TwinCATDataType.Date or TwinCATDataType.DateTime:
{
// DATE / DT publish a UTC DateTime, as a scalar does (#306).
var a = new DateTime[n];
for (var i = 0; i < n; i++)
a[i] = (DateTime)TwinCATTemporalCodec.Decode(declared, BinaryPrimitives.ReadUInt32LittleEndian(bytes[(i * stride)..]));
return a;
}
case TwinCATDataType.LInt:
{
var a = new long[n];