From d1c05bd20d6d4686e9a41315e90ee22d38ec9c7d Mon Sep 17 00:00:00 2001 From: Wenhao Song <32570730+songwenhao1@users.noreply.github.com> Date: Fri, 28 Jun 2019 11:17:18 +0800 Subject: [PATCH] Revise .NET DateTime after recent extensions (#1673) - Add a null check in new code; - Fix resolution in tagged cases like "saint patrick" and "five-thirty tomorrow evening". --- .../English/DateTimeDefinitions.cs | 4 +- .../Parsers/BaseMergedDateTimeParser.cs | 6 ++- .../parsers/BaseMergedDateTimeParser.java | 5 +- .../datetime/resources/EnglishDateTime.java | 4 +- .../src/resources/englishDateTime.ts | 4 +- Patterns/English/English-DateTime.yaml | 4 +- .../resources/english_date_time.py | 4 +- Specs/DateTime/English/DateTimeModel.json | 47 +++++++++++++++++++ .../English/DateTimeModelComplexCalendar.json | 47 +++++++++++++++++++ 9 files changed, 113 insertions(+), 12 deletions(-) diff --git a/.NET/Microsoft.Recognizers.Definitions.Common/English/DateTimeDefinitions.cs b/.NET/Microsoft.Recognizers.Definitions.Common/English/DateTimeDefinitions.cs index 32cdbc992e..a6fc924b43 100644 --- a/.NET/Microsoft.Recognizers.Definitions.Common/English/DateTimeDefinitions.cs +++ b/.NET/Microsoft.Recognizers.Definitions.Common/English/DateTimeDefinitions.cs @@ -166,7 +166,7 @@ public static class DateTimeDefinitions public static readonly string TimeRegex6 = $@"{BasicTime}(\s*{DescRegex})?\s+{TimeSuffix}\b"; public static readonly string TimeRegex7 = $@"\b{TimeSuffixFull}\s+(at\s+)?{BasicTime}((\s*{DescRegex})|\b)"; public static readonly string TimeRegex8 = $@".^"; - public static readonly string TimeRegex9 = $@"\b{PeriodHourNumRegex}\s+{FivesRegex}((\s*{DescRegex})|\b)"; + public static readonly string TimeRegex9 = $@"\b{PeriodHourNumRegex}(\s+|-){FivesRegex}((\s*{DescRegex})|\b)"; public static readonly string TimeRegex10 = $@"\b({TimePrefix}\s+)?{BaseDateTime.HourRegex}(\s*h\s*){BaseDateTime.MinuteRegex}(\s*{DescRegex})?"; public static readonly string TimeRegex11 = $@"\b(?:(?:{TimeTokenPrefix}{TimeRegexWithDotConnector})(?!\s*per\s*cent|%)|(?:{TimeRegexWithDotConnector}(\s*{DescRegex})))"; public static readonly string FirstTimeRegexInTimeRange = $@"\b{TimeRegexWithDotConnector}(\s*{DescRegex})?"; @@ -639,7 +639,7 @@ public static class DateTimeDefinitions { @"inaugurationday", new string[] { @"inaugurationday" } }, { @"groundhougday", new string[] { @"groundhougday" } }, { @"valentinesday", new string[] { @"valentinesday" } }, - { @"stpatrickday", new string[] { @"stpatrickday", @"stpatricksday" } }, + { @"stpatrickday", new string[] { @"stpatrickday", @"stpatricksday", "stpatrick" } }, { @"aprilfools", new string[] { @"aprilfools" } }, { @"stgeorgeday", new string[] { @"stgeorgeday" } }, { @"mayday", new string[] { @"mayday", @"intlworkersday", @"internationalworkersday" } }, diff --git a/.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseMergedDateTimeParser.cs b/.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseMergedDateTimeParser.cs index 85bc2f26d2..a35c9b0550 100644 --- a/.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseMergedDateTimeParser.cs +++ b/.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseMergedDateTimeParser.cs @@ -414,7 +414,11 @@ public DateTimeParseResult Parse(ExtractResult er, DateObject refTime) else { var hasRangeChangingMod = hasBefore || hasAfter || hasSince; - ((DateTimeResolutionResult)pr.Value).HasRangeChangingMod = hasRangeChangingMod; + if (pr.Value != null) + { + ((DateTimeResolutionResult)pr.Value).HasRangeChangingMod = hasRangeChangingMod; + } + pr = SetParseResult(pr, hasRangeChangingMod); } diff --git a/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseMergedDateTimeParser.java b/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseMergedDateTimeParser.java index 9f37b00233..0c828d242d 100644 --- a/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseMergedDateTimeParser.java +++ b/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/parsers/BaseMergedDateTimeParser.java @@ -257,7 +257,10 @@ public DateTimeParseResult parse(ExtractResult er, LocalDateTime reference) { pr.setValue(dateTimeResolutionForSplit(pr)); } else { boolean hasModifier = hasBefore || hasAfter || hasSince; - ((DateTimeResolutionResult)pr.getValue()).setHasRangeChangingMod(hasModifier); + if (pr.getValue() != null) { + ((DateTimeResolutionResult)pr.getValue()).setHasRangeChangingMod(hasModifier); + } + pr = setParseResult(pr, hasModifier); } diff --git a/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/resources/EnglishDateTime.java b/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/resources/EnglishDateTime.java index c2dc2c19a4..f80ee5f6e5 100644 --- a/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/resources/EnglishDateTime.java +++ b/Java/libraries/recognizers-text-date-time/src/main/java/com/microsoft/recognizers/text/datetime/resources/EnglishDateTime.java @@ -523,7 +523,7 @@ public class EnglishDateTime { .replace("{BasicTime}", BasicTime) .replace("{DescRegex}", DescRegex); - public static final String TimeRegex9 = "\\b{PeriodHourNumRegex}\\s+{FivesRegex}((\\s*{DescRegex})|\\b)" + public static final String TimeRegex9 = "\\b{PeriodHourNumRegex}(\\s+|-){FivesRegex}((\\s*{DescRegex})|\\b)" .replace("{PeriodHourNumRegex}", PeriodHourNumRegex) .replace("{FivesRegex}", FivesRegex) .replace("{DescRegex}", DescRegex); @@ -1249,7 +1249,7 @@ public class EnglishDateTime { .put("inaugurationday", new String[]{"inaugurationday"}) .put("groundhougday", new String[]{"groundhougday"}) .put("valentinesday", new String[]{"valentinesday"}) - .put("stpatrickday", new String[]{"stpatrickday", "stpatricksday"}) + .put("stpatrickday", new String[]{"stpatrickday", "stpatricksday", "stpatrick"}) .put("aprilfools", new String[]{"aprilfools"}) .put("stgeorgeday", new String[]{"stgeorgeday"}) .put("mayday", new String[]{"mayday", "intlworkersday", "internationalworkersday"}) diff --git a/JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts b/JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts index cc11367f3b..0fb97545cb 100644 --- a/JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts +++ b/JavaScript/packages/recognizers-date-time/src/resources/englishDateTime.ts @@ -156,7 +156,7 @@ export namespace EnglishDateTime { export const TimeRegex6 = `${BasicTime}(\\s*${DescRegex})?\\s+${TimeSuffix}\\b`; export const TimeRegex7 = `\\b${TimeSuffixFull}\\s+(at\\s+)?${BasicTime}((\\s*${DescRegex})|\\b)`; export const TimeRegex8 = `.^`; - export const TimeRegex9 = `\\b${PeriodHourNumRegex}\\s+${FivesRegex}((\\s*${DescRegex})|\\b)`; + export const TimeRegex9 = `\\b${PeriodHourNumRegex}(\\s+|-)${FivesRegex}((\\s*${DescRegex})|\\b)`; export const TimeRegex10 = `\\b(${TimePrefix}\\s+)?${BaseDateTime.HourRegex}(\\s*h\\s*)${BaseDateTime.MinuteRegex}(\\s*${DescRegex})?`; export const TimeRegex11 = `\\b(?:(?:${TimeTokenPrefix}${TimeRegexWithDotConnector})(?!\\s*per\\s*cent|%)|(?:${TimeRegexWithDotConnector}(\\s*${DescRegex})))`; export const FirstTimeRegexInTimeRange = `\\b${TimeRegexWithDotConnector}(\\s*${DescRegex})?`; @@ -272,7 +272,7 @@ export namespace EnglishDateTime { export const Numbers: ReadonlyMap = new Map([["zero", 0],["one", 1],["a", 1],["an", 1],["two", 2],["three", 3],["four", 4],["five", 5],["six", 6],["seven", 7],["eight", 8],["nine", 9],["ten", 10],["eleven", 11],["twelve", 12],["thirteen", 13],["fourteen", 14],["fifteen", 15],["sixteen", 16],["seventeen", 17],["eighteen", 18],["nineteen", 19],["twenty", 20],["twenty one", 21],["twenty two", 22],["twenty three", 23],["twenty four", 24],["twenty five", 25],["twenty six", 26],["twenty seven", 27],["twenty eight", 28],["twenty nine", 29],["thirty", 30],["thirty one", 31],["thirty two", 32],["thirty three", 33],["thirty four", 34],["thirty five", 35],["thirty six", 36],["thirty seven", 37],["thirty eight", 38],["thirty nine", 39],["forty", 40],["forty one", 41],["forty two", 42],["forty three", 43],["forty four", 44],["forty five", 45],["forty six", 46],["forty seven", 47],["forty eight", 48],["forty nine", 49],["fifty", 50],["fifty one", 51],["fifty two", 52],["fifty three", 53],["fifty four", 54],["fifty five", 55],["fifty six", 56],["fifty seven", 57],["fifty eight", 58],["fifty nine", 59],["sixty", 60],["sixty one", 61],["sixty two", 62],["sixty three", 63],["sixty four", 64],["sixty five", 65],["sixty six", 66],["sixty seven", 67],["sixty eight", 68],["sixty nine", 69],["seventy", 70],["seventy one", 71],["seventy two", 72],["seventy three", 73],["seventy four", 74],["seventy five", 75],["seventy six", 76],["seventy seven", 77],["seventy eight", 78],["seventy nine", 79],["eighty", 80],["eighty one", 81],["eighty two", 82],["eighty three", 83],["eighty four", 84],["eighty five", 85],["eighty six", 86],["eighty seven", 87],["eighty eight", 88],["eighty nine", 89],["ninety", 90],["ninety one", 91],["ninety two", 92],["ninety three", 93],["ninety four", 94],["ninety five", 95],["ninety six", 96],["ninety seven", 97],["ninety eight", 98],["ninety nine", 99],["one hundred", 100]]); export const DayOfMonth: ReadonlyMap = new Map([["1st", 1],["2nd", 2],["3rd", 3],["4th", 4],["5th", 5],["6th", 6],["7th", 7],["8th", 8],["9th", 9],["10th", 10],["11th", 11],["11st", 11],["12th", 12],["12nd", 12],["13th", 13],["13rd", 13],["14th", 14],["15th", 15],["16th", 16],["17th", 17],["18th", 18],["19th", 19],["20th", 20],["21st", 21],["21th", 21],["22nd", 22],["22th", 22],["23rd", 23],["23th", 23],["24th", 24],["25th", 25],["26th", 26],["27th", 27],["28th", 28],["29th", 29],["30th", 30],["31st", 31],["01st", 1],["02nd", 2],["03rd", 3],["04th", 4],["05th", 5],["06th", 6],["07th", 7],["08th", 8],["09th", 9]]); export const DoubleNumbers: ReadonlyMap = new Map([["half", 0.5],["quarter", 0.25]]); - export const HolidayNames: ReadonlyMap = new Map([["easterday", ["easterday","easter","eastersunday"]],["ashwednesday", ["ashwednesday"]],["palmsunday", ["palmsunday"]],["maundythursday", ["maundythursday"]],["goodfriday", ["goodfriday"]],["eastersaturday", ["eastersaturday"]],["eastermonday", ["eastermonday"]],["ascensionday", ["ascensionday"]],["whitesunday", ["whitesunday","pentecost","pentecostday"]],["whitemonday", ["whitemonday"]],["trinitysunday", ["trinitysunday"]],["corpuschristi", ["corpuschristi"]],["earthday", ["earthday"]],["fathers", ["fatherday","fathersday"]],["mothers", ["motherday","mothersday"]],["thanksgiving", ["thanksgivingday","thanksgiving"]],["blackfriday", ["blackfriday"]],["cybermonday", ["cybermonday"]],["martinlutherking", ["mlkday","martinlutherkingday","martinlutherkingjrday"]],["washingtonsbirthday", ["washingtonsbirthday","washingtonbirthday","presidentsday"]],["canberra", ["canberraday"]],["labour", ["labourday","laborday"]],["columbus", ["columbusday"]],["memorial", ["memorialday"]],["yuandan", ["yuandan"]],["maosbirthday", ["maosbirthday"]],["teachersday", ["teachersday","teacherday"]],["singleday", ["singleday"]],["allsaintsday", ["allsaintsday"]],["youthday", ["youthday"]],["childrenday", ["childrenday","childday"]],["femaleday", ["femaleday"]],["treeplantingday", ["treeplantingday"]],["arborday", ["arborday"]],["girlsday", ["girlsday"]],["whiteloverday", ["whiteloverday"]],["loverday", ["loverday"]],["christmas", ["christmasday","christmas"]],["xmas", ["xmasday","xmas"]],["newyear", ["newyear"]],["newyearday", ["newyearday"]],["newyearsday", ["newyearsday"]],["inaugurationday", ["inaugurationday"]],["groundhougday", ["groundhougday"]],["valentinesday", ["valentinesday"]],["stpatrickday", ["stpatrickday","stpatricksday"]],["aprilfools", ["aprilfools"]],["stgeorgeday", ["stgeorgeday"]],["mayday", ["mayday","intlworkersday","internationalworkersday"]],["cincodemayoday", ["cincodemayoday"]],["baptisteday", ["baptisteday"]],["usindependenceday", ["usindependenceday"]],["independenceday", ["independenceday"]],["bastilleday", ["bastilleday"]],["halloweenday", ["halloweenday","halloween"]],["allhallowday", ["allhallowday"]],["allsoulsday", ["allsoulsday"]],["guyfawkesday", ["guyfawkesday"]],["veteransday", ["veteransday"]],["christmaseve", ["christmaseve"]],["newyeareve", ["newyearseve","newyeareve"]]]); + export const HolidayNames: ReadonlyMap = new Map([["easterday", ["easterday","easter","eastersunday"]],["ashwednesday", ["ashwednesday"]],["palmsunday", ["palmsunday"]],["maundythursday", ["maundythursday"]],["goodfriday", ["goodfriday"]],["eastersaturday", ["eastersaturday"]],["eastermonday", ["eastermonday"]],["ascensionday", ["ascensionday"]],["whitesunday", ["whitesunday","pentecost","pentecostday"]],["whitemonday", ["whitemonday"]],["trinitysunday", ["trinitysunday"]],["corpuschristi", ["corpuschristi"]],["earthday", ["earthday"]],["fathers", ["fatherday","fathersday"]],["mothers", ["motherday","mothersday"]],["thanksgiving", ["thanksgivingday","thanksgiving"]],["blackfriday", ["blackfriday"]],["cybermonday", ["cybermonday"]],["martinlutherking", ["mlkday","martinlutherkingday","martinlutherkingjrday"]],["washingtonsbirthday", ["washingtonsbirthday","washingtonbirthday","presidentsday"]],["canberra", ["canberraday"]],["labour", ["labourday","laborday"]],["columbus", ["columbusday"]],["memorial", ["memorialday"]],["yuandan", ["yuandan"]],["maosbirthday", ["maosbirthday"]],["teachersday", ["teachersday","teacherday"]],["singleday", ["singleday"]],["allsaintsday", ["allsaintsday"]],["youthday", ["youthday"]],["childrenday", ["childrenday","childday"]],["femaleday", ["femaleday"]],["treeplantingday", ["treeplantingday"]],["arborday", ["arborday"]],["girlsday", ["girlsday"]],["whiteloverday", ["whiteloverday"]],["loverday", ["loverday"]],["christmas", ["christmasday","christmas"]],["xmas", ["xmasday","xmas"]],["newyear", ["newyear"]],["newyearday", ["newyearday"]],["newyearsday", ["newyearsday"]],["inaugurationday", ["inaugurationday"]],["groundhougday", ["groundhougday"]],["valentinesday", ["valentinesday"]],["stpatrickday", ["stpatrickday","stpatricksday","stpatrick"]],["aprilfools", ["aprilfools"]],["stgeorgeday", ["stgeorgeday"]],["mayday", ["mayday","intlworkersday","internationalworkersday"]],["cincodemayoday", ["cincodemayoday"]],["baptisteday", ["baptisteday"]],["usindependenceday", ["usindependenceday"]],["independenceday", ["independenceday"]],["bastilleday", ["bastilleday"]],["halloweenday", ["halloweenday","halloween"]],["allhallowday", ["allhallowday"]],["allsoulsday", ["allsoulsday"]],["guyfawkesday", ["guyfawkesday"]],["veteransday", ["veteransday"]],["christmaseve", ["christmaseve"]],["newyeareve", ["newyearseve","newyeareve"]]]); export const WrittenDecades: ReadonlyMap = new Map([["hundreds", 0],["tens", 10],["twenties", 20],["thirties", 30],["forties", 40],["fifties", 50],["sixties", 60],["seventies", 70],["eighties", 80],["nineties", 90]]); export const SpecialDecadeCases: ReadonlyMap = new Map([["noughties", 2000],["aughts", 2000],["two thousands", 2000]]); export const DefaultLanguageFallback = 'MDY'; diff --git a/Patterns/English/English-DateTime.yaml b/Patterns/English/English-DateTime.yaml index e1ebe967dc..0d53c6a573 100644 --- a/Patterns/English/English-DateTime.yaml +++ b/Patterns/English/English-DateTime.yaml @@ -382,7 +382,7 @@ TimeRegex8: !nestedRegex def: .^ references: [ TimeSuffixFull, BasicTime, DescRegex ] TimeRegex9: !nestedRegex - def: \b{PeriodHourNumRegex}\s+{FivesRegex}((\s*{DescRegex})|\b) + def: \b{PeriodHourNumRegex}(\s+|-){FivesRegex}((\s*{DescRegex})|\b) references: [ PeriodHourNumRegex, FivesRegex, DescRegex ] TimeRegex10: !nestedRegex def: \b({TimePrefix}\s+)?{BaseDateTime.HourRegex}(\s*h\s*){BaseDateTime.MinuteRegex}(\s*{DescRegex})? @@ -1020,7 +1020,7 @@ HolidayNames: !dictionary inaugurationday: [ inaugurationday ] groundhougday: [ groundhougday ] valentinesday: [ valentinesday ] - stpatrickday: [ stpatrickday, stpatricksday ] + stpatrickday: [ stpatrickday, stpatricksday, stpatrick ] aprilfools: [ aprilfools ] stgeorgeday: [ stgeorgeday ] mayday: [ mayday, intlworkersday, internationalworkersday ] diff --git a/Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py b/Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py index 934ff28a6b..721277f729 100644 --- a/Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py +++ b/Python/libraries/recognizers-date-time/recognizers_date_time/resources/english_date_time.py @@ -159,7 +159,7 @@ class EnglishDateTime: TimeRegex6 = f'{BasicTime}(\\s*{DescRegex})?\\s+{TimeSuffix}\\b' TimeRegex7 = f'\\b{TimeSuffixFull}\\s+(at\\s+)?{BasicTime}((\\s*{DescRegex})|\\b)' TimeRegex8 = f'.^' - TimeRegex9 = f'\\b{PeriodHourNumRegex}\\s+{FivesRegex}((\\s*{DescRegex})|\\b)' + TimeRegex9 = f'\\b{PeriodHourNumRegex}(\\s+|-){FivesRegex}((\\s*{DescRegex})|\\b)' TimeRegex10 = f'\\b({TimePrefix}\\s+)?{BaseDateTime.HourRegex}(\\s*h\\s*){BaseDateTime.MinuteRegex}(\\s*{DescRegex})?' TimeRegex11 = f'\\b(?:(?:{TimeTokenPrefix}{TimeRegexWithDotConnector})(?!\\s*per\\s*cent|%)|(?:{TimeRegexWithDotConnector}(\\s*{DescRegex})))' FirstTimeRegexInTimeRange = f'\\b{TimeRegexWithDotConnector}(\\s*{DescRegex})?' @@ -597,7 +597,7 @@ class EnglishDateTime: ("inaugurationday", ["inaugurationday"]), ("groundhougday", ["groundhougday"]), ("valentinesday", ["valentinesday"]), - ("stpatrickday", ["stpatrickday", "stpatricksday"]), + ("stpatrickday", ["stpatrickday", "stpatricksday", "stpatrick"]), ("aprilfools", ["aprilfools"]), ("stgeorgeday", ["stgeorgeday"]), ("mayday", ["mayday", "intlworkersday", "internationalworkersday"]), diff --git a/Specs/DateTime/English/DateTimeModel.json b/Specs/DateTime/English/DateTimeModel.json index 50ce071381..dece085388 100644 --- a/Specs/DateTime/English/DateTimeModel.json +++ b/Specs/DateTime/English/DateTimeModel.json @@ -12400,5 +12400,52 @@ } } ] + }, + { + "Input": "I'll go back on saint patrick 2020", + "Context": { + "ReferenceDateTime": "2019-06-28T00:00:00" + }, + "NotSupported": "python, javascript, java", + "Results": [ + { + "Text": "saint patrick 2020", + "Start": 16, + "End": 33, + "TypeName": "datetimeV2.date", + "Resolution": { + "values": [ + { + "timex": "2020-03-17", + "type": "date", + "value": "2020-03-17" + } + ] + } + } + ] + }, + { + "Input": "I'll go back at five-thirty tomorrow evening", + "Context": { + "ReferenceDateTime": "2019-06-28T00:00:00" + }, + "Results": [ + { + "Text": "five-thirty tomorrow evening", + "Start": 16, + "End": 43, + "TypeName": "datetimeV2.datetime", + "Resolution": { + "values": [ + { + "timex": "2019-06-29T17:30", + "type": "datetime", + "value": "2019-06-29 17:30:00" + } + ] + } + } + ] } ] \ No newline at end of file diff --git a/Specs/DateTime/English/DateTimeModelComplexCalendar.json b/Specs/DateTime/English/DateTimeModelComplexCalendar.json index 4efec959ea..562dd91791 100644 --- a/Specs/DateTime/English/DateTimeModelComplexCalendar.json +++ b/Specs/DateTime/English/DateTimeModelComplexCalendar.json @@ -10567,5 +10567,52 @@ } } ] + }, + { + "Input": "I'll go back on saint patrick 2020", + "Context": { + "ReferenceDateTime": "2019-06-28T00:00:00" + }, + "NotSupported": "python, javascript, java", + "Results": [ + { + "Text": "saint patrick 2020", + "Start": 16, + "End": 33, + "TypeName": "datetimeV2.date", + "Resolution": { + "values": [ + { + "timex": "2020-03-17", + "type": "date", + "value": "2020-03-17" + } + ] + } + } + ] + }, + { + "Input": "I'll go back at five-thirty tomorrow evening", + "Context": { + "ReferenceDateTime": "2019-06-28T00:00:00" + }, + "Results": [ + { + "Text": "five-thirty tomorrow evening", + "Start": 16, + "End": 43, + "TypeName": "datetimeV2.datetime", + "Resolution": { + "values": [ + { + "timex": "2019-06-29T17:30", + "type": "datetime", + "value": "2019-06-29 17:30:00" + } + ] + } + } + ] } ] \ No newline at end of file