|
| 1 | +using System; |
| 2 | +using S7.Net.Helper; |
| 3 | + |
| 4 | +namespace S7.Net.Types |
| 5 | +{ |
| 6 | + /// <summary> |
| 7 | + /// Contains the conversion methods to convert Words from S7 plc to C#. |
| 8 | + /// </summary> |
| 9 | + public static class Date |
| 10 | + { |
| 11 | + /// <summary> |
| 12 | + /// Minimum allowed date for the IEC date type |
| 13 | + /// </summary> |
| 14 | + public static System.DateTime IecMinDate { get; } = new(year: 1990, month: 01, day: 01); |
| 15 | + |
| 16 | + /// <summary> |
| 17 | + /// Maximum allowed date for the IEC date type |
| 18 | + /// <remarks> |
| 19 | + /// 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 |
| 20 | + /// WORD max value - 65535) |
| 21 | + /// </remarks> |
| 22 | + /// </summary> |
| 23 | + public static System.DateTime IecMaxDate { get; } = new(year: 2169, month: 06, day: 06); |
| 24 | + |
| 25 | + private static readonly ushort MaxNumberOfDays = (ushort)(IecMaxDate - IecMinDate).TotalDays; |
| 26 | + |
| 27 | + /// <summary> |
| 28 | + /// Converts a word (2 bytes) to IEC date (<see cref="System.DateTime"/>) |
| 29 | + /// </summary> |
| 30 | + public static System.DateTime FromByteArray(byte[] bytes) |
| 31 | + { |
| 32 | + if (bytes.Length != 2) |
| 33 | + { |
| 34 | + throw new ArgumentException("Wrong number of bytes. Bytes array must contain 2 bytes."); |
| 35 | + } |
| 36 | + |
| 37 | + var daysSinceDateStart = Word.FromByteArray(bytes); |
| 38 | + if (daysSinceDateStart > MaxNumberOfDays) |
| 39 | + { |
| 40 | + throw new ArgumentException($"Read number exceeded the number of maximum days in the IEC date (read: {daysSinceDateStart}, max: {MaxNumberOfDays})", |
| 41 | + nameof(bytes)); |
| 42 | + } |
| 43 | + |
| 44 | + return IecMinDate.AddDays(daysSinceDateStart); |
| 45 | + } |
| 46 | + |
| 47 | + /// <summary> |
| 48 | + /// Converts a <see cref="System.DateTime"/> to word (2 bytes) |
| 49 | + /// </summary> |
| 50 | + public static byte[] ToByteArray(System.DateTime dateTime) => Word.ToByteArray(dateTime.GetDaysSinceIecDateStart()); |
| 51 | + |
| 52 | + /// <summary> |
| 53 | + /// Converts an array of <see cref="System.DateTime"/>s to an array of bytes |
| 54 | + /// </summary> |
| 55 | + public static byte[] ToByteArray(System.DateTime[] value) |
| 56 | + { |
| 57 | + var arr = new ByteArray(); |
| 58 | + foreach (var date in value) |
| 59 | + arr.Add(ToByteArray(date)); |
| 60 | + return arr.Array; |
| 61 | + } |
| 62 | + |
| 63 | + /// <summary> |
| 64 | + /// Converts an array of bytes to an array of <see cref="System.DateTime"/>s |
| 65 | + /// </summary> |
| 66 | + public static System.DateTime[] ToArray(byte[] bytes) |
| 67 | + { |
| 68 | + var values = new System.DateTime[bytes.Length / sizeof(ushort)]; |
| 69 | + |
| 70 | + for (int i = 0; i < values.Length; i++) |
| 71 | + { |
| 72 | + values[i] = FromByteArray( |
| 73 | + new[] |
| 74 | + { |
| 75 | + bytes[i], bytes[i + 1] |
| 76 | + }); |
| 77 | + } |
| 78 | + |
| 79 | + return values; |
| 80 | + } |
| 81 | + } |
| 82 | +} |
0 commit comments