diff --git a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs index e61483d..84cc5b9 100644 --- a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs +++ b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs @@ -73,6 +73,19 @@ namespace JT808.Protocol.Test.MessagePack Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); } + [Fact] + public void ReadDateTimeNullTest() + { + byte[] bytes = "7E0000000000000000000000000000007E".ToHexBytes(); + JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes); + Assert.Equal(JT808Package.BeginFlag, jT808MessagePackReader.ReadStart()); + Assert.Null(jT808MessagePackReader.ReadDateTimeNull4()); + Assert.Null(jT808MessagePackReader.ReadDateTimeNull5()); + Assert.Null(jT808MessagePackReader.ReadDateTimeNull6()); + Assert.Equal(JT808Package.EndFlag, jT808MessagePackReader.ReadEnd()); + } + + [Theory] [InlineData("smallchi(Koike)")] public void ReadStringTest(string str) diff --git a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs index 51415cb..aeea4f5 100644 --- a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs +++ b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs @@ -77,6 +77,25 @@ namespace JT808.Protocol.Test.MessagePack Assert.Equal("7E2019061923232301231906192323237E7E2019061923232301231906192323237E", realBytes); } + [Fact] + public void WriteDateTimeNullTest() + { + byte[] array = new byte[4096]; + var msgpackWriter = new JT808MessagePackWriter(array); + msgpackWriter.WriteStart(); + msgpackWriter.WriteDateTime4(null); + msgpackWriter.WriteDateTime5(null); + msgpackWriter.WriteDateTime6(null); + msgpackWriter.WriteEnd(); + msgpackWriter.WriteEncode(); + //===========output========= + //WriteDateTime4=>YYYYMMDD=>00 00 00 00 + //WriteDateTime5=>HH-mm-ss-fff|HH-mm-ss-msms=>00 00 00 00 00 + //WriteDateTime6=>yyMMddHHmmss=>00 00 00 00 + var encodeBytes = msgpackWriter.FlushAndGetEncodingArray().ToHexString(); + Assert.Equal("7E0000000000000000000000000000007E".Replace(" ", ""), encodeBytes); + } + [Fact] public void WriteUTCDateTimeTest() { diff --git a/src/JT808.Protocol/JT808.Protocol.csproj b/src/JT808.Protocol/JT808.Protocol.csproj index 7ff3d05..00f5060 100644 --- a/src/JT808.Protocol/JT808.Protocol.csproj +++ b/src/JT808.Protocol/JT808.Protocol.csproj @@ -59,12 +59,12 @@ - + - + diff --git a/src/JT808.Protocol/JT808.Protocol.xml b/src/JT808.Protocol/JT808.Protocol.xml index 596e482..1f9f0f5 100644 --- a/src/JT808.Protocol/JT808.Protocol.xml +++ b/src/JT808.Protocol/JT808.Protocol.xml @@ -8012,6 +8012,12 @@ >D2: 10 X2:16 + + + yyMMddHHmmss + + >D2: 10 X2:16 + HH-mm-ss-msms @@ -8019,18 +8025,37 @@ D2: 10 X2:16 + + + HH-mm-ss-msms + HH-mm-ss-fff + + D2: 10 X2:16 + YYYYMMDD D2: 10 X2:16 + + + YYYYMMDD + + D2: 10 X2:16 + YYMMDD D2: 10 X2:16 + + + YYMMDD + + D2: 10 X2:16 + yyMMddHHmmss @@ -8038,6 +8063,13 @@ + + + yyMMddHHmmss + + + + HH-mm-ss-msms @@ -8046,6 +8078,14 @@ + + + HH-mm-ss-msms + HH-mm-ss-fff + + + + YYYYMMDD @@ -8055,6 +8095,15 @@ + + + YYYYMMDD + BCD[4] + 数据形如:20200101 + + + + YYMMDD @@ -8064,6 +8113,15 @@ + + + YYMMDD + BCD[4] + 数据形如:20200101 + + + + 数字编码 大端模式、高位在前 diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs index 1639a8f..ed5c9a3 100644 --- a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs +++ b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs @@ -263,6 +263,31 @@ namespace JT808.Protocol.MessagePack return d; } /// + /// yyMMddHHmmss + /// + /// >D2: 10 X2:16 + public DateTime? ReadDateTimeNull6(string format = "X2") + { + DateTime? d; + try + { + var readOnlySpan = GetReadOnlySpan(6); + int year = Convert.ToInt32(readOnlySpan[0].ToString(format)) ; + int month = Convert.ToInt32(readOnlySpan[1].ToString(format)); + int day = Convert.ToInt32(readOnlySpan[2].ToString(format)); + int hour = Convert.ToInt32(readOnlySpan[3].ToString(format)); + int minute = Convert.ToInt32(readOnlySpan[4].ToString(format)); + int second = Convert.ToInt32(readOnlySpan[5].ToString(format)); + if (year == 0 && month == 0 && day == 0 && hour == 0 && minute == 0 && second == 0) return null; + d = new DateTime(year + JT808Constants.DateLimitYear, month, day, hour, minute, second); + } + catch (Exception) + { + return null; + } + return d; + } + /// /// HH-mm-ss-msms /// HH-mm-ss-fff /// @@ -274,8 +299,8 @@ namespace JT808.Protocol.MessagePack { var readOnlySpan = GetReadOnlySpan(5); StringBuilder sb = new StringBuilder(4); - sb.Append(readOnlySpan[3].ToString("X2")); - sb.Append(readOnlySpan[4].ToString("X2")); + sb.Append(readOnlySpan[3].ToString(format)); + sb.Append(readOnlySpan[4].ToString(format)); d = new DateTime( DateTime.Now.Year, DateTime.Now.Month, @@ -292,6 +317,40 @@ namespace JT808.Protocol.MessagePack return d; } /// + /// HH-mm-ss-msms + /// HH-mm-ss-fff + /// + /// D2: 10 X2:16 + public DateTime? ReadDateTimeNull5(string format = "X2") + { + DateTime? d; + try + { + var readOnlySpan = GetReadOnlySpan(5); + StringBuilder sb = new StringBuilder(4); + sb.Append(readOnlySpan[3].ToString("X2")); + sb.Append(readOnlySpan[4].ToString("X2")); + int hour = Convert.ToInt32(readOnlySpan[0].ToString(format)); + int minute = Convert.ToInt32(readOnlySpan[1].ToString(format)); + int second = Convert.ToInt32(readOnlySpan[2].ToString(format)); + int millisecond = Convert.ToInt32(sb.ToString().TrimStart()); + if (hour == 0 && minute == 0 && second == 0 && millisecond == 0) return null; + d = new DateTime( + DateTime.Now.Year, + DateTime.Now.Month, + DateTime.Now.Day, + hour, + minute, + second, + millisecond); + } + catch + { + return null; + } + return d; + } + /// /// YYYYMMDD /// /// D2: 10 X2:16 @@ -302,8 +361,8 @@ namespace JT808.Protocol.MessagePack { var readOnlySpan = GetReadOnlySpan(4); StringBuilder sb = new StringBuilder(4); - sb.Append(readOnlySpan[0].ToString("X2")); - sb.Append(readOnlySpan[1].ToString("X2")); + sb.Append(readOnlySpan[0].ToString(format)); + sb.Append(readOnlySpan[1].ToString(format)); d = new DateTime( Convert.ToInt32(sb.ToString()), Convert.ToInt32(readOnlySpan[2].ToString(format)), @@ -316,6 +375,31 @@ namespace JT808.Protocol.MessagePack return d; } /// + /// YYYYMMDD + /// + /// D2: 10 X2:16 + public DateTime? ReadDateTimeNull4(string format = "X2") + { + DateTime? d; + try + { + var readOnlySpan = GetReadOnlySpan(4); + StringBuilder sb = new StringBuilder(4); + sb.Append(readOnlySpan[0].ToString(format)); + sb.Append(readOnlySpan[1].ToString(format)); + int year = Convert.ToInt32(sb.ToString()); + int month = Convert.ToInt32(readOnlySpan[2].ToString(format)); + int day = Convert.ToInt32(readOnlySpan[3].ToString(format)); + if (year == 0 && month == 0 && day == 0) return null; + d = new DateTime(year, month, day); + } + catch (Exception) + { + return null; + } + return d; + } + /// /// YYMMDD /// /// D2: 10 X2:16 @@ -336,6 +420,30 @@ namespace JT808.Protocol.MessagePack } return d; } + /// + /// YYMMDD + /// + /// D2: 10 X2:16 + public DateTime? ReadDateTimeNull3(string format = "X2") + { + DateTime? d; + try + { + var readOnlySpan = GetReadOnlySpan(3); + int year =Convert.ToInt32(readOnlySpan[0].ToString(format)); + int month=Convert.ToInt32(readOnlySpan[1].ToString(format)); + int day = Convert.ToInt32(readOnlySpan[2].ToString(format)); + if (year == 0 && month == 0 && day == 0) return null; + d = new DateTime( + year + JT808Constants.DateLimitYear, month,day + ); + } + catch (Exception) + { + d = JT808Constants.UTCBaseTime; + } + return d; + } public DateTime ReadUTCDateTime() { DateTime d; diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs index fee1854..dbaa9dc 100644 --- a/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs +++ b/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs @@ -172,6 +172,34 @@ namespace JT808.Protocol.MessagePack writer.Advance(6); } /// + /// yyMMddHHmmss + /// + /// + /// + public void WriteDateTime6(DateTime? value, int fromBase = 16) + { + var span = writer.Free; + if (value == null || value.HasValue) + { + span[0] = 0; + span[1] = 0; + span[2] = 0; + span[3] = 0; + span[4] = 0; + span[5] = 0; + } + else + { + span[0] = Convert.ToByte(value.Value.ToString("yy"), fromBase); + span[1] = Convert.ToByte(value.Value.ToString("MM"), fromBase); + span[2] = Convert.ToByte(value.Value.ToString("dd"), fromBase); + span[3] = Convert.ToByte(value.Value.ToString("HH"), fromBase); + span[4] = Convert.ToByte(value.Value.ToString("mm"), fromBase); + span[5] = Convert.ToByte(value.Value.ToString("ss"), fromBase); + } + writer.Advance(6); + } + /// /// HH-mm-ss-msms /// HH-mm-ss-fff /// @@ -188,6 +216,34 @@ namespace JT808.Protocol.MessagePack span[4] = Convert.ToByte(msSpan.Slice(2, 2).ToString(), fromBase); writer.Advance(5); } + /// + /// HH-mm-ss-msms + /// HH-mm-ss-fff + /// + /// + /// + public void WriteDateTime5(DateTime? value, int fromBase = 16) + { + var span = writer.Free; + if (value == null || value.HasValue) + { + span[0] = 0; + span[1] = 0; + span[2] = 0; + span[3] = 0; + span[4] = 0; + } + else + { + span[0] = Convert.ToByte(value.Value.ToString("HH"), fromBase); + span[1] = Convert.ToByte(value.Value.ToString("mm"), fromBase); + span[2] = Convert.ToByte(value.Value.ToString("ss"), fromBase); + var msSpan = value.Value.Millisecond.ToString().PadLeft(4, '0').AsSpan(); + span[3] = Convert.ToByte(msSpan.Slice(0, 2).ToString(), fromBase); + span[4] = Convert.ToByte(msSpan.Slice(2, 2).ToString(), fromBase); + } + writer.Advance(5); + } public void WriteUTCDateTime(DateTime value) { ulong totalSecends = (ulong)(value.AddHours(-8) - JT808Constants.UTCBaseTime).TotalSeconds; @@ -217,6 +273,35 @@ namespace JT808.Protocol.MessagePack span[3] = Convert.ToByte(value.ToString("dd"), fromBase); writer.Advance(4); } + + /// + /// YYYYMMDD + /// BCD[4] + /// 数据形如:20200101 + /// + /// + /// + public void WriteDateTime4(DateTime? value, int fromBase = 16) + { + var span = writer.Free; + if (value==null || value.HasValue) + { + span[0] = 0; + span[1] = 0; + span[2] = 0; + span[3] = 0; + } + else + { + var yearSpan = value.Value.ToString("yyyy").AsSpan(); + span[0] = Convert.ToByte(yearSpan.Slice(0, 2).ToString(), fromBase); + span[1] = Convert.ToByte(yearSpan.Slice(2, 2).ToString(), fromBase); + span[2] = Convert.ToByte(value.Value.ToString("MM"), fromBase); + span[3] = Convert.ToByte(value.Value.ToString("dd"), fromBase); + } + writer.Advance(4); + } + /// /// YYMMDD /// BCD[4] @@ -232,6 +317,31 @@ namespace JT808.Protocol.MessagePack span[2] = Convert.ToByte(value.ToString("dd"), fromBase); writer.Advance(3); } + + /// + /// YYMMDD + /// BCD[4] + /// 数据形如:20200101 + /// + /// + /// + public void WriteDateTime3(DateTime? value, int fromBase = 16) + { + var span = writer.Free; + if (value == null || value.HasValue) + { + span[0] = 0; + span[1] = 0; + span[2] = 0; + } + else + { + span[0] = Convert.ToByte(value.Value.ToString("yy"), fromBase); + span[1] = Convert.ToByte(value.Value.ToString("MM"), fromBase); + span[2] = Convert.ToByte(value.Value.ToString("dd"), fromBase); + } + writer.Advance(3); + } public void WriteXor(int start, int end) { if (start > end)