diff --git a/src/Microsoft.DotNet.Interactive.Http.Parsing/Parsing/DynamicExpressionUtilities.cs b/src/Microsoft.DotNet.Interactive.Http.Parsing/Parsing/DynamicExpressionUtilities.cs index bef237d347..01c9e16571 100644 --- a/src/Microsoft.DotNet.Interactive.Http.Parsing/Parsing/DynamicExpressionUtilities.cs +++ b/src/Microsoft.DotNet.Interactive.Http.Parsing/Parsing/DynamicExpressionUtilities.cs @@ -168,6 +168,8 @@ private static DateTimeOffset DefaultGetDateTimeOffset(bool isLocal) var formatProvider = Thread.CurrentThread.CurrentUICulture; var type = match.Groups["type"]; + string? text = null; + // $datetime and $localDatetime MUST have either rfc1123, iso8601 or some other parameter. // $datetime or $localDatetime alone should result in a binding error. if (type is not null && !string.IsNullOrWhiteSpace(type.Value)) @@ -179,10 +181,16 @@ private static DateTimeOffset DefaultGetDateTimeOffset(bool isLocal) // we should explicitly set the format provider to invariant culture formatProvider = CultureInfo.InvariantCulture; format = "r"; + } else if (string.Equals(type.Value, "iso8601", StringComparison.OrdinalIgnoreCase)) { format = "o"; + if (currentDateTimeOffset.Offset.TotalMinutes == 0) + { + // for $datetime, format the DateTime in order to eliminate the +00:00 offset and use Z + text = currentDateTimeOffset.UtcDateTime.ToString(format, formatProvider); + } } else { @@ -192,7 +200,11 @@ private static DateTimeOffset DefaultGetDateTimeOffset(bool isLocal) try { - string text = currentDateTimeOffset.ToString(format, formatProvider); + if(text is null) + { + text = currentDateTimeOffset.ToString(format, formatProvider); + } + return node.CreateBindingSuccess(text); } catch (FormatException) diff --git a/src/Microsoft.DotNet.Interactive.Http.Tests/ParserTests.DynamicExpressions.cs b/src/Microsoft.DotNet.Interactive.Http.Tests/ParserTests.DynamicExpressions.cs index 100c5ae798..5b81fb3875 100644 --- a/src/Microsoft.DotNet.Interactive.Http.Tests/ParserTests.DynamicExpressions.cs +++ b/src/Microsoft.DotNet.Interactive.Http.Tests/ParserTests.DynamicExpressions.cs @@ -52,7 +52,7 @@ public void can_bind_datetime_with_iso8601_format() var code = $@"@var = {{{{{expression}}}}}"""; var result = HttpRequestParser.Parse(code); - var currentTime = DateTimeOffset.UtcNow; + var currentTime = DateTimeOffset.UtcNow.UtcDateTime; var node = result.SyntaxTree.RootNode.DescendantNodesAndTokens().OfType().Single(); var binding = DynamicExpressionUtilities.ResolveExpressionBinding(node, () => currentTime, expression); @@ -66,7 +66,7 @@ public void can_bind_datetime_with_iso8601_format_with_offset() var code = $@"@var = {{{{{expression}}}}}"""; var result = HttpRequestParser.Parse(code); - var currentTime = DateTimeOffset.UtcNow; + var currentTime = DateTimeOffset.UtcNow.UtcDateTime; var node = result.SyntaxTree.RootNode.DescendantNodesAndTokens().OfType().Single(); var binding = DynamicExpressionUtilities.ResolveExpressionBinding(node, () => currentTime, expression); @@ -139,7 +139,7 @@ public void can_bind_local_datetime_with_iso8601_format() var code = $@"@var = {{{{{expression}}}}}"""; var result = HttpRequestParser.Parse(code); - var currentTime = DateTimeOffset.Now; + var currentTime = DateTimeOffset.UtcNow.UtcDateTime; var node = result.SyntaxTree.RootNode.DescendantNodesAndTokens().OfType().Single(); var binding = DynamicExpressionUtilities.ResolveExpressionBinding(node, () => currentTime, expression); @@ -153,7 +153,7 @@ public void can_bind_local_datetime_with_iso8601_format_with_offset() var code = $@"@var = {{{{{expression}}}}}"""; var result = HttpRequestParser.Parse(code); - var currentTime = DateTimeOffset.Now; + var currentTime = DateTimeOffset.UtcNow.UtcDateTime; var node = result.SyntaxTree.RootNode.DescendantNodesAndTokens().OfType().Single(); var binding = DynamicExpressionUtilities.ResolveExpressionBinding(node, () => currentTime, expression);