Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DynamoDB SDK convert Nullable DateTime to Local #3351

Closed
nazarii-piontko opened this issue Jun 21, 2024 · 4 comments
Closed

DynamoDB SDK convert Nullable DateTime to Local #3351

nazarii-piontko opened this issue Jun 21, 2024 · 4 comments
Labels
bug This issue is a bug. dynamodb p1 This is a high priority issue queued

Comments

@nazarii-piontko
Copy link

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

@nazarii-piontko nazarii-piontko added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Jun 21, 2024
@ashishdhingra ashishdhingra self-assigned this Jun 21, 2024
@ashishdhingra ashishdhingra added needs-reproduction This issue needs reproduction. and removed needs-triage This issue or PR still needs to be triaged. labels Jun 21, 2024
@ashishdhingra
Copy link
Contributor

Needs reproduction.

@ashishdhingra ashishdhingra added needs-review and removed needs-reproduction This issue needs reproduction. labels Jun 21, 2024
@bhoradc bhoradc added p1 This is a high priority issue needs-reproduction This issue needs reproduction. and removed needs-review labels Jun 21, 2024
@bhoradc
Copy link

bhoradc commented Jun 21, 2024

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

@philasmar
Copy link
Contributor

We have released a fix for this issue in AWSSDK.DynamoDBv2 3.7.304.1

Copy link

github-actions bot commented Jul 1, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. dynamodb p1 This is a high priority issue queued
Projects
None yet
Development

No branches or pull requests

4 participants