From fc6d97be398ad593b5950fb4991473aa9b4306dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B0=D0=BC=D0=BE=20=D0=9F=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Tue, 15 Jun 2021 09:38:03 +0300 Subject: [PATCH 1/4] Custom DateTime converter added --- dgc/DGCDateTimeConverter.cs | 115 ++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 dgc/DGCDateTimeConverter.cs diff --git a/dgc/DGCDateTimeConverter.cs b/dgc/DGCDateTimeConverter.cs new file mode 100644 index 0000000..64a2abd --- /dev/null +++ b/dgc/DGCDateTimeConverter.cs @@ -0,0 +1,115 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; + +namespace DGC +{ + /// + /// Digital Green Certificate Date Time Converter + /// + public class DGCDateTimeConverter : IsoDateTimeConverter + { + private readonly IEnumerable<(string pattern, string format)> formatters; + + /// + /// Initialize converter with default values + /// + public DGCDateTimeConverter() + { + formatters = new (string pattern, string formatter)[] + { + // Formates 'sc' and 'dr' in 't' array as ISO 8601 Date + // If pattern matches JSON Path, formatter is used + (@"t\[\d\]\.(sc|dr)", "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK") + }; + + this.DateTimeFormat = "yyyy-MM-dd"; + this.Culture = CultureInfo.InvariantCulture; + } + + /// + /// Initialize converter with custom formatters + /// + /// Collection of Custom formatters + public DGCDateTimeConverter(IEnumerable<(string pattern, string format)> _formatters) + : this() + { + formatters = _formatters; + } + + /// + /// Serializes Dates with given format + /// + /// Writes value as string + /// Date to be serialized + /// Serializer settings + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + string text = null; + + try + { + if (value is DateTime dateTime) + { + if (formatters == null || formatters.Count() == 0) + { + text = dateTime + .ToUniversalTime() + .ToString(DateTimeFormat, Culture); + } + else + { + foreach (var formatter in formatters) + { + Regex tester = new Regex(formatter.pattern); + + if (tester.IsMatch(writer.Path)) + { + text = dateTime + .ToUniversalTime() + .ToString(formatter.format, Culture); + } + } + } + } + else if (value is DateTimeOffset dateTimeOffset) + { + if (formatters == null || formatters.Count() == 0) + { + text = dateTimeOffset + .ToUniversalTime() + .ToString(DateTimeFormat, Culture); + } + else + { + foreach (var formatter in formatters) + { + Regex tester = new Regex(formatter.pattern); + + if (tester.IsMatch(writer.Path)) + { + text = dateTimeOffset + .ToUniversalTime() + .ToString(formatter.format, Culture); + } + } + } + } + else + { + throw new ArgumentException(); + } + + writer.WriteValue(text); + } + catch (Exception) + { + base.WriteJson(writer, value, serializer); + } + } + } +} From 922f37e19a64458ba78a3abf84d8f85dd13997ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B0=D0=BC=D0=BE=20=D0=9F=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Tue, 15 Jun 2021 09:38:24 +0300 Subject: [PATCH 2/4] Custom converter added to CWT --- dgc/CWT.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dgc/CWT.cs b/dgc/CWT.cs index 16df0d7..e90c5dc 100644 --- a/dgc/CWT.cs +++ b/dgc/CWT.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using PeterO.Cbor; using System; +using System.Collections.Generic; namespace DGC { @@ -46,7 +47,15 @@ internal byte[] EncodeToBytes() var cborHcer = CBORObject.NewMap(); - var json = JsonConvert.SerializeObject(DGCv1); + var json = JsonConvert.SerializeObject(DGCv1, new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore, + Converters = new List() + { + new DGCDateTimeConverter() + } + }); + cborHcer[1] = CBORObject.FromJSONString(json); cbor[Header_HCERT] = cborHcer; From 47cf829814705efeee8706c9f25e24f6785816d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B0=D0=BC=D0=BE=20=D0=9F=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Tue, 15 Jun 2021 13:51:29 +0300 Subject: [PATCH 3/4] DGCDateTimeConverter set value if no formatter match --- dgc/DGCDateTimeConverter.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dgc/DGCDateTimeConverter.cs b/dgc/DGCDateTimeConverter.cs index 64a2abd..5fb125c 100644 --- a/dgc/DGCDateTimeConverter.cs +++ b/dgc/DGCDateTimeConverter.cs @@ -74,6 +74,13 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s .ToString(formatter.format, Culture); } } + + if (text == null) + { + text = dateTime + .ToUniversalTime() + .ToString(DateTimeFormat, Culture); + } } } else if (value is DateTimeOffset dateTimeOffset) @@ -97,6 +104,13 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s .ToString(formatter.format, Culture); } } + + if (text == null) + { + text = dateTimeOffset + .ToUniversalTime() + .ToString(DateTimeFormat, Culture); + } } } else From 96d3e417a9a6ee982a5af8c9c3c6d866e39a843a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B0=D0=BC=D0=BE=20=D0=9F=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Tue, 15 Jun 2021 14:21:51 +0300 Subject: [PATCH 4/4] Test for DGCDateTimeConverter added --- dgc.tests/UnitTest1.cs | 98 +++++++++++++++++++++++++++++++++++++ dgc/DGCDateTimeConverter.cs | 2 +- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/dgc.tests/UnitTest1.cs b/dgc.tests/UnitTest1.cs index c0e2157..dec2412 100644 --- a/dgc.tests/UnitTest1.cs +++ b/dgc.tests/UnitTest1.cs @@ -52,6 +52,35 @@ private static CWT CreateCWTTestData() return cwt; } + private static DgCertificate CreateTestEntryCertificate() + { + return new DgCertificate() + { + DateOfBirth = new DateTimeOffset(1978, 1, 26, 0, 0, 0, TimeSpan.Zero), + Name = new Nam() + { + FamilyName = "Ïåòêîâ", + GivenName = "Ñòàìî Ãåîðãèåâ", + FamilyNameTransliterated = "Petkov", + GivenNameTraslitaerated = "Stamo + /// Testing DGCDateTimeConverter + /// Only TestEntry has different types of dates + /// + [TestMethod] + public void SerializeDates() + { + var cert = CreateTestEntryCertificate(); + var json = Newtonsoft.Json.JsonConvert.SerializeObject(cert, new Newtonsoft.Json.JsonSerializerSettings() + { + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + Converters = new List() + { + new DGCDateTimeConverter() + } + }); + + Assert.IsTrue(json.Contains("\"dob\":\"1978-01-26\"")); + Assert.IsTrue(json.Contains("\"sc\":\"2021-06-14T09:37:58+00:00\"")); + Assert.IsTrue(json.Contains("\"dr\":\"2021-06-15T08:45:12+00:00\"")); + } + + /// + /// Testing DGCDateTimeConverter with default format + /// + [TestMethod] + public void SerializeDatesWithoutTime() + { + var cert = CreateTestEntryCertificate(); + var json = Newtonsoft.Json.JsonConvert.SerializeObject(cert, new Newtonsoft.Json.JsonSerializerSettings() + { + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + Converters = new List() + { + new DGCDateTimeConverter(null) + } + }); + + Assert.IsTrue(json.Contains("\"dob\":\"1978-01-26\"")); + Assert.IsTrue(json.Contains("\"sc\":\"2021-06-14\"")); + Assert.IsTrue(json.Contains("\"dr\":\"2021-06-15\"")); + } + + /// + /// Testing DGCDateTimeConverter with special formatters + /// + [TestMethod] + public void SerializeDatesWithSpecialFormat() + { + var cert = CreateTestEntryCertificate(); + var json = Newtonsoft.Json.JsonConvert.SerializeObject(cert, new Newtonsoft.Json.JsonSerializerSettings() + { + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + Converters = new List() + { + new DGCDateTimeConverter(new (string, string)[] + { + ("dob", "yy-MM-dd"), + (@"t\[\d+\]\.(sc)", "yyyy"), + (@"t\[\d+\]\.(dr)", "yyyy-MM") + }) + } + }); + + Assert.IsTrue(json.Contains("\"dob\":\"78-01-26\"")); + Assert.IsTrue(json.Contains("\"sc\":\"2021\"")); + Assert.IsTrue(json.Contains("\"dr\":\"2021-06\"")); + } } } diff --git a/dgc/DGCDateTimeConverter.cs b/dgc/DGCDateTimeConverter.cs index 5fb125c..3a98230 100644 --- a/dgc/DGCDateTimeConverter.cs +++ b/dgc/DGCDateTimeConverter.cs @@ -24,7 +24,7 @@ public DGCDateTimeConverter() { // Formates 'sc' and 'dr' in 't' array as ISO 8601 Date // If pattern matches JSON Path, formatter is used - (@"t\[\d\]\.(sc|dr)", "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK") + (@"t\[\d+\]\.(sc|dr)", "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK") }; this.DateTimeFormat = "yyyy-MM-dd";