aws / aws-sdk-net

The official AWS SDK for .NET. For more information on the AWS SDK for .NET, see our web site:

Home Page:http://aws.amazon.com/sdkfornet/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.