diff --git a/libraries/src/AWS.Lambda.Powertools.Logging/Internal/Converters/DateOnlyConverter.cs b/libraries/src/AWS.Lambda.Powertools.Logging/Internal/Converters/DateOnlyConverter.cs
new file mode 100644
index 00000000..a6f969e5
--- /dev/null
+++ b/libraries/src/AWS.Lambda.Powertools.Logging/Internal/Converters/DateOnlyConverter.cs
@@ -0,0 +1,52 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+using System;
+using System.Globalization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace AWS.Lambda.Powertools.Logging.Internal.Converters;
+
+///
+/// DateOnly JSON converter
+///
+public class DateOnlyConverter : JsonConverter
+{
+ private const string DateFormat = "yyyy-MM-dd";
+
+ ///
+ /// Converts DateOnly from JSON.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return DateOnly.ParseExact(reader.GetString()!, DateFormat, CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Converts DateOnly to JSON.
+ ///
+ ///
+ ///
+ ///
+ public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value.ToString(DateFormat, CultureInfo.InvariantCulture));
+ }
+}
\ No newline at end of file
diff --git a/libraries/src/AWS.Lambda.Powertools.Logging/Internal/Converters/TimeOnlyConverter.cs b/libraries/src/AWS.Lambda.Powertools.Logging/Internal/Converters/TimeOnlyConverter.cs
new file mode 100644
index 00000000..737362ca
--- /dev/null
+++ b/libraries/src/AWS.Lambda.Powertools.Logging/Internal/Converters/TimeOnlyConverter.cs
@@ -0,0 +1,52 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+using System;
+using System.Globalization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace AWS.Lambda.Powertools.Logging.Internal.Converters;
+
+///
+/// TimeOnly JSON converter
+///
+internal class TimeOnlyConverter : JsonConverter
+{
+ private const string TimeFormat = "HH:mm:ss.FFFFFFF";
+
+ ///
+ /// Converts TimeOnly from JSON.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ return TimeOnly.ParseExact(reader.GetString()!, TimeFormat, CultureInfo.InvariantCulture);
+ }
+
+ ///
+ /// Converts TimeOnly to JSON.
+ ///
+ ///
+ ///
+ ///
+ public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value.ToString(TimeFormat, CultureInfo.InvariantCulture));
+ }
+}
\ No newline at end of file
diff --git a/libraries/src/AWS.Lambda.Powertools.Logging/Internal/LoggingAspectHandler.cs b/libraries/src/AWS.Lambda.Powertools.Logging/Internal/LoggingAspectHandler.cs
index 4b262490..441cdc22 100644
--- a/libraries/src/AWS.Lambda.Powertools.Logging/Internal/LoggingAspectHandler.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Logging/Internal/LoggingAspectHandler.cs
@@ -288,6 +288,8 @@ private static JsonSerializerOptions BuildJsonSerializerOptions()
jsonOptions.Converters.Add(new ExceptionConverter());
jsonOptions.Converters.Add(new MemoryStreamConverter());
jsonOptions.Converters.Add(new ConstantClassConverter());
+ jsonOptions.Converters.Add(new DateOnlyConverter());
+ jsonOptions.Converters.Add(new TimeOnlyConverter());
return jsonOptions;
}
diff --git a/libraries/src/AWS.Lambda.Powertools.Logging/Internal/PowertoolsLogger.cs b/libraries/src/AWS.Lambda.Powertools.Logging/Internal/PowertoolsLogger.cs
index 265090aa..707d4a8e 100644
--- a/libraries/src/AWS.Lambda.Powertools.Logging/Internal/PowertoolsLogger.cs
+++ b/libraries/src/AWS.Lambda.Powertools.Logging/Internal/PowertoolsLogger.cs
@@ -466,6 +466,8 @@ private JsonSerializerOptions BuildJsonSerializerOptions()
jsonOptions.Converters.Add(new ExceptionConverter());
jsonOptions.Converters.Add(new MemoryStreamConverter());
jsonOptions.Converters.Add(new ConstantClassConverter());
+ jsonOptions.Converters.Add(new DateOnlyConverter());
+ jsonOptions.Converters.Add(new TimeOnlyConverter());
jsonOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
diff --git a/libraries/tests/AWS.Lambda.Powertools.Logging.Tests/PowertoolsLoggerTest.cs b/libraries/tests/AWS.Lambda.Powertools.Logging.Tests/PowertoolsLoggerTest.cs
index 71db5932..c0fd3c09 100644
--- a/libraries/tests/AWS.Lambda.Powertools.Logging.Tests/PowertoolsLoggerTest.cs
+++ b/libraries/tests/AWS.Lambda.Powertools.Logging.Tests/PowertoolsLoggerTest.cs
@@ -1219,5 +1219,87 @@ public void Log_Set_Execution_Environment_Context()
$"{Constants.FeatureContextIdentifier}/Logger/{assemblyVersion}");
env.Received(1).GetEnvironmentVariable("AWS_EXECUTION_ENV");
}
+
+ [Fact]
+ public void Log_Should_Serialize_DateOnly()
+ {
+ // Arrange
+ var loggerName = Guid.NewGuid().ToString();
+ var service = Guid.NewGuid().ToString();
+ var logLevel = LogLevel.Information;
+ var randomSampleRate = 0.5;
+
+ var configurations = Substitute.For();
+ configurations.Service.Returns(service);
+ configurations.LogLevel.Returns(logLevel.ToString());
+
+ var systemWrapper = Substitute.For();
+ systemWrapper.GetRandom().Returns(randomSampleRate);
+
+ var logger = new PowertoolsLogger(loggerName, configurations, systemWrapper, () =>
+ new LoggerConfiguration
+ {
+ Service = null,
+ MinimumLevel = null,
+ LoggerOutputCase = LoggerOutputCase.CamelCase
+ });
+
+ var message = new
+ {
+ PropOne = "Value 1",
+ PropTwo = "Value 2",
+ Date = new DateOnly(2022, 1, 1)
+ };
+
+ logger.LogInformation(message);
+
+ // Assert
+ systemWrapper.Received(1).LogLine(
+ Arg.Is(s =>
+ s.Contains("\"message\":{\"propOne\":\"Value 1\",\"propTwo\":\"Value 2\",\"date\":\"2022-01-01\"}")
+ )
+ );
+ }
+
+ [Fact]
+ public void Log_Should_Serialize_TimeOnly()
+ {
+ // Arrange
+ var loggerName = Guid.NewGuid().ToString();
+ var service = Guid.NewGuid().ToString();
+ var logLevel = LogLevel.Information;
+ var randomSampleRate = 0.5;
+
+ var configurations = Substitute.For();
+ configurations.Service.Returns(service);
+ configurations.LogLevel.Returns(logLevel.ToString());
+
+ var systemWrapper = Substitute.For();
+ systemWrapper.GetRandom().Returns(randomSampleRate);
+
+ var logger = new PowertoolsLogger(loggerName, configurations, systemWrapper, () =>
+ new LoggerConfiguration
+ {
+ Service = null,
+ MinimumLevel = null,
+ LoggerOutputCase = LoggerOutputCase.CamelCase
+ });
+
+ var message = new
+ {
+ PropOne = "Value 1",
+ PropTwo = "Value 2",
+ Time = new TimeOnly(12, 0, 0)
+ };
+
+ logger.LogInformation(message);
+
+ // Assert
+ systemWrapper.Received(1).LogLine(
+ Arg.Is(s =>
+ s.Contains("\"message\":{\"propOne\":\"Value 1\",\"propTwo\":\"Value 2\",\"time\":\"12:00:00\"}")
+ )
+ );
+ }
}
}
\ No newline at end of file