DynamoDB SDK convert Nullable DateTime to Local
nazarii-piontko opened this issue · comments
Describe the bug
The DynamoDB SDK ignores RetrieveDateTimeInUtc = true
in DynamoDBContextConfig
when serialized/deserialized property has type DateTime?
(nullable DateTime).
Expected Behavior
The DynamoDB SDK should not convert DateTime?
saved in the table as UTC to Local time upon retrieval when DynamoDBContextConfig.RetrieveDateTimeInUtc
is set to true
.
Current Behavior
The DynamoDB SDK converts DateTime?
saved in the table as UTC to Local time upon retrieval when DynamoDBContextConfig.RetrieveDateTimeInUtc
is set to true
.
Reproduction Steps
using System.Diagnostics;
using System.Globalization;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
var dynDbClient = new AmazonDynamoDBClient();
var dynDbContext = new DynamoDBContext(dynDbClient, new DynamoDBContextConfig
{
RetrieveDateTimeInUtc = true
});
var user = new User
{
UserId = Guid.NewGuid(),
AppointmentDateTime = DateTime.Parse("2024-06-24T08:00:00.000Z", styles: DateTimeStyles.AdjustToUniversal)
};
await dynDbContext.SaveAsync(user);
var dbUser = await dynDbContext.LoadAsync<User?>(user.UserId);
Debug.Assert(user.AppointmentDateTime == dbUser?.AppointmentDateTime);
[DynamoDBTable("users")]
public class User
{
[DynamoDBHashKey("userId")]
public Guid UserId { get; set; }
[DynamoDBProperty("appointmentSlot")]
public DateTime? AppointmentDateTime { get; set; }
}
Prerequisites:
- Access to AWS DynamoDB with default credentials.
- Existence of DynamoDB table with name
users
.
Possible Solution
File: src/Services/DynamoDBv2/Custom/DataModel/ContextInternal.cs, Line: 470
Existing code:
if (targetType == typeof(DateTime) && flatConfig.RetrieveDateTimeInUtc)
{
return ((DateTime)output).ToUniversalTime();
}
Replace to something like this:
if (targetType == typeof(DateTime) && flatConfig.RetrieveDateTimeInUtc)
{
return ((DateTime)output).ToUniversalTime();
}
else if (targetType == typeof(DateTime?) && flatConfig.RetrieveDateTimeInUtc)
{
return ((DateTime?)output)?.ToUniversalTime();
}
Additional Information/Context
From csproj
:
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
AWS .NET SDK and/or Package version used
AWSSDK.DynamoDBv2 3.7.303.16
Targeted .NET Platform
.NET 8
Operating System and version
Windows 10
Needs reproduction.
Hello @nazarii-piontko,
Thank you for reporting this issue. I am able to reproduce it using below code sample.
static async Task Main(string[] args)
{
var dynDbClient = new AmazonDynamoDBClient();
var dynDbContext = new DynamoDBContext(dynDbClient, new DynamoDBContextConfig
{
RetrieveDateTimeInUtc = true
});
var user = new User
{
UserId = Guid.NewGuid(),
AppointmentDateTime = DateTime.Parse("2024-06-24T08:00:00.000Z", styles: DateTimeStyles.AdjustToUniversal)
};
await dynDbContext.SaveAsync(user);
var dbUser = await dynDbContext.LoadAsync<User?>(user.UserId);
Console.WriteLine("AppointmentDateTime: "+dbUser.AppointmentDateTime);
}
[DynamoDBTable("users")]
public class User
{
[DynamoDBHashKey("userId")]
public Guid UserId { get; set; }
[DynamoDBProperty("appointmentSlot")]
public DateTime? AppointmentDateTime { get; set; }
}
Before running the code sample, created DynamoDB table with name users
and Partition key as userId
(string).
Execution Result: AppointmentDateTime: 6/24/2024 4:00:00 AM
With RetrieveDateTimeInUtc = true
, it still converts the DB saved time 2024-06-24T08:00:00.000Z
to 6/24/2024 4:00:00 AM
local time upon retrieval.
The .NET SDK team will investigate and work on the fix for this. Thanks again for reporting this case with the Nullable DateTime scenario.
Regards,
Chaitanya
We have released a fix for this issue in AWSSDK.DynamoDBv2 3.7.304.1
Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.