diff --git a/S7.Net/Enums.cs b/S7.Net/Enums.cs
index 080dce65..3eb7e4ba 100644
--- a/S7.Net/Enums.cs
+++ b/S7.Net/Enums.cs
@@ -202,6 +202,11 @@ public enum VarType
/// DateTIme variable type
///
DateTime,
+
+ ///
+ /// IEC date (legacy) variable type
+ ///
+ Date,
///
/// DateTimeLong variable type
diff --git a/S7.Net/Helper/DateTimeExtensions.cs b/S7.Net/Helper/DateTimeExtensions.cs
new file mode 100644
index 00000000..62432ee1
--- /dev/null
+++ b/S7.Net/Helper/DateTimeExtensions.cs
@@ -0,0 +1,23 @@
+using System;
+using S7.Net.Types;
+using DateTime = System.DateTime;
+
+namespace S7.Net.Helper
+{
+ public static class DateTimeExtensions
+ {
+ public static ushort GetDaysSinceIecDateStart(this DateTime dateTime)
+ {
+ if (dateTime < Date.IecMinDate)
+ {
+ throw new ArgumentOutOfRangeException($"DateTime must be at least {Date.IecMinDate:d}");
+ }
+ if (dateTime > Date.IecMaxDate)
+ {
+ throw new ArgumentOutOfRangeException($"DateTime must be lower than {Date.IecMaxDate:d}");
+ }
+
+ return (ushort)(dateTime - Date.IecMinDate).TotalDays;
+ }
+ }
+}
\ No newline at end of file
diff --git a/S7.Net/PLCHelpers.cs b/S7.Net/PLCHelpers.cs
index fc6bb141..c85a2383 100644
--- a/S7.Net/PLCHelpers.cs
+++ b/S7.Net/PLCHelpers.cs
@@ -251,6 +251,15 @@ private static void BuildReadDataRequestPackage(System.IO.MemoryStream stream, D
{
return TimeSpan.ToArray(bytes);
}
+ case VarType.Date:
+ if (varCount == 1)
+ {
+ return Date.FromByteArray(bytes);
+ }
+ else
+ {
+ return Date.ToArray(bytes);
+ }
default:
return null;
}
@@ -280,6 +289,7 @@ internal static int VarTypeToByteLength(VarType varType, int varCount = 1)
case VarType.Timer:
case VarType.Int:
case VarType.Counter:
+ case VarType.Date:
return varCount * 2;
case VarType.DWord:
case VarType.DInt:
diff --git a/S7.Net/Protocol/Serialization.cs b/S7.Net/Protocol/Serialization.cs
index 3d114b6f..fce3bef1 100644
--- a/S7.Net/Protocol/Serialization.cs
+++ b/S7.Net/Protocol/Serialization.cs
@@ -26,6 +26,11 @@ public static byte[] SerializeDataItem(DataItem dataItem)
_ => Types.String.ToByteArray(s, dataItem.Count)
};
+ if (dataItem.VarType == VarType.Date)
+ {
+ return Date.ToByteArray((System.DateTime)dataItem.Value);
+ }
+
return SerializeValue(dataItem.Value);
}
diff --git a/S7.Net/Types/Date.cs b/S7.Net/Types/Date.cs
new file mode 100644
index 00000000..5c53f19d
--- /dev/null
+++ b/S7.Net/Types/Date.cs
@@ -0,0 +1,82 @@
+using System;
+using S7.Net.Helper;
+
+namespace S7.Net.Types
+{
+ ///
+ /// Contains the conversion methods to convert Words from S7 plc to C#.
+ ///
+ public static class Date
+ {
+ ///
+ /// Minimum allowed date for the IEC date type
+ ///
+ public static System.DateTime IecMinDate { get; } = new(year: 1990, month: 01, day: 01);
+
+ ///
+ /// Maximum allowed date for the IEC date type
+ ///
+ /// Although the spec allows only a max date of 31-12-2168, the PLC IEC date goes up to 06-06-2169 (which is the actual
+ /// WORD max value - 65535)
+ ///
+ ///
+ public static System.DateTime IecMaxDate { get; } = new(year: 2169, month: 06, day: 06);
+
+ private static readonly ushort MaxNumberOfDays = (ushort)(IecMaxDate - IecMinDate).TotalDays;
+
+ ///
+ /// Converts a word (2 bytes) to IEC date ()
+ ///
+ public static System.DateTime FromByteArray(byte[] bytes)
+ {
+ if (bytes.Length != 2)
+ {
+ throw new ArgumentException("Wrong number of bytes. Bytes array must contain 2 bytes.");
+ }
+
+ var daysSinceDateStart = Word.FromByteArray(bytes);
+ if (daysSinceDateStart > MaxNumberOfDays)
+ {
+ throw new ArgumentException($"Read number exceeded the number of maximum days in the IEC date (read: {daysSinceDateStart}, max: {MaxNumberOfDays})",
+ nameof(bytes));
+ }
+
+ return IecMinDate.AddDays(daysSinceDateStart);
+ }
+
+ ///
+ /// Converts a to word (2 bytes)
+ ///
+ public static byte[] ToByteArray(System.DateTime dateTime) => Word.ToByteArray(dateTime.GetDaysSinceIecDateStart());
+
+ ///
+ /// Converts an array of s to an array of bytes
+ ///
+ public static byte[] ToByteArray(System.DateTime[] value)
+ {
+ var arr = new ByteArray();
+ foreach (var date in value)
+ arr.Add(ToByteArray(date));
+ return arr.Array;
+ }
+
+ ///
+ /// Converts an array of bytes to an array of s
+ ///
+ public static System.DateTime[] ToArray(byte[] bytes)
+ {
+ var values = new System.DateTime[bytes.Length / sizeof(ushort)];
+
+ for (int i = 0; i < values.Length; i++)
+ {
+ values[i] = FromByteArray(
+ new[]
+ {
+ bytes[i], bytes[i + 1]
+ });
+ }
+
+ return values;
+ }
+ }
+}