diff --git a/src/Microsoft.OData.Core/UriParser/Parsers/LiteralParser.cs b/src/Microsoft.OData.Core/UriParser/Parsers/LiteralParser.cs index 27217cec57..a1d5e657d3 100644 --- a/src/Microsoft.OData.Core/UriParser/Parsers/LiteralParser.cs +++ b/src/Microsoft.OData.Core/UriParser/Parsers/LiteralParser.cs @@ -12,6 +12,7 @@ namespace Microsoft.OData.Core.UriParser.Parsers using System.Globalization; using System.Text; using System.Xml; + using Edm.Library; using Microsoft.Spatial; using XmlConstants = ExpressionConstants; @@ -37,6 +38,7 @@ internal abstract class LiteralParser { typeof(byte[]), new BinaryPrimitiveParser() }, { typeof(String), new StringPrimitiveParser() }, { typeof(Decimal), new DecimalPrimitiveParser() }, + { typeof(Date), new DatePrimitiveParser() }, // Types without single-quotes or type markers { typeof(Boolean), DelegatingPrimitiveParser.WithoutMarkup(XmlConvert.ToBoolean) }, @@ -626,5 +628,52 @@ internal override bool TryRemoveFormatting(ref string text) return UriPrimitiveTypeParser.TryRemoveQuotes(ref text); } } + + /// + /// Parser specific to the Edm.Date type. + /// + private sealed class DatePrimitiveParser : PrimitiveParser + { + /// + /// Initializes a new instance of the class. + /// + public DatePrimitiveParser() : base(typeof(Date)) + { + } + + /// + /// Tries to convert the given text into this parser's expected type. Conversion only, formatting should already have been removed. + /// + /// The text to convert. + /// The target value. + /// + /// Whether or not conversion was successful. + /// + internal override bool TryConvert(string text, out object targetValue) + { + try + { + var date = XmlConvert.ToDateTimeOffset(text); + targetValue = new Date(date.Year, date.Month, date.Day); + } + catch (FormatException) + { + targetValue = null; + return false; + } + catch (ArgumentOutOfRangeException) + { + targetValue = null; + return false; + } + catch (ArgumentNullException) + { + targetValue = null; + return false; + } + + return true; + } + } } } diff --git a/test/FunctionalTests/Tests/DataOData/Tests/OData.Query.TDD.Tests/Syntactic/LIteralParserUnitTests.cs b/test/FunctionalTests/Tests/DataOData/Tests/OData.Query.TDD.Tests/Syntactic/LIteralParserUnitTests.cs index 39103f9b7f..27aef2dd4b 100644 --- a/test/FunctionalTests/Tests/DataOData/Tests/OData.Query.TDD.Tests/Syntactic/LIteralParserUnitTests.cs +++ b/test/FunctionalTests/Tests/DataOData/Tests/OData.Query.TDD.Tests/Syntactic/LIteralParserUnitTests.cs @@ -4,6 +4,8 @@ // //--------------------------------------------------------------------- +using Microsoft.OData.Edm.Library; + namespace Microsoft.Test.OData.Query.TDD.Tests.Syntactic { using System; @@ -47,5 +49,14 @@ public void TryParseLiteralWithDurationLiteralForKeyAsSegmentUrlConventionsShoul parser.TryParseLiteral(typeof(TimeSpan), "P1D", out output).Should().BeTrue(); output.ShouldBeEquivalentTo(new TimeSpan(1, 0, 0, 0)); } + + [TestMethod] + public void TryParseLiteralWithDateForKeyAsSegmentUrlConventionsShouldReturnValidDate() + { + var parser = LiteralParser.ForKeys(true /*keyAsSegment*/); + object output; + parser.TryParseLiteral(typeof(Date), "2015-09-28", out output).Should().BeTrue(); + output.ShouldBeEquivalentTo(new Date(2015, 09, 28)); + } } }