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

DateTimeOffset property changed offset after SaveAsync #504

Open
Jimmys20 opened this issue Nov 20, 2024 · 3 comments · May be fixed by #505
Open

DateTimeOffset property changed offset after SaveAsync #504

Jimmys20 opened this issue Nov 20, 2024 · 3 comments · May be fixed by #505

Comments

@Jimmys20
Copy link

Jimmys20 commented Nov 20, 2024

Hello, I have a model with a DateTimeOffset property that I store on redis. When I insert a new entry using InsertAsync the DateTimeOffset property has the correct offset but after calling SaveAsync the offset changes. It looks like it changes to the local timezone offset of the machine where redis-server is running.

Demo to reproduce: https://github.com/Jimmys20/RedisOMDateTimeOffset

[Document(StorageType = StorageType.Json, Prefixes = ["Player"])]
public class PlayerEntity
{
    [RedisIdField, Indexed] public string UniquePlayerId { get; set; }
    public DateTimeOffset StartTime { get; set; }
}

internal class Program
{
    static async Task Main(string[] args)
    {
        var redisConfigurationOptions = new StackExchange.Redis.ConfigurationOptions
        {
            EndPoints = { "192.168.100.4:6379" },
            User = null,
            Password = null,
            AllowAdmin = false,
            Ssl = false,
        };

        var provider = new RedisConnectionProvider(redisConfigurationOptions);

        provider.Connection.DropIndexAndAssociatedRecords(typeof(PlayerEntity));
        await provider.Connection.CreateIndexAsync(typeof(PlayerEntity));

        var players = provider.RedisCollection<PlayerEntity>();

        var uniquePlayerId = Guid.NewGuid().ToString();
        var startTime = new DateTimeOffset(2024, 11, 21, 12, 30, 00, new TimeSpan(1, 0, 0));

        await players.InsertAsync(new PlayerEntity
        {
            UniquePlayerId = uniquePlayerId,
            StartTime = startTime,
        });

        var player = await players.FindByIdAsync(uniquePlayerId);

        await players.SaveAsync();

        var player2 = await players.FindByIdAsync(uniquePlayerId);

        Console.WriteLine(player.StartTime); // 21/11/2024 12:30:00 +01:00
        Console.WriteLine(player2.StartTime); // 21/11/2024 13:30:00 +02:00
        Console.WriteLine(player.StartTime.Offset == player2.StartTime.Offset); // False
    }
}

After InsertAsync:

127.0.0.1:6379> json.get "Player:5c9274f3-e852-4e03-a3b7-424b8679bf99"
"{\"UniquePlayerId\":\"5c9274f3-e852-4e03-a3b7-424b8679bf99\",\"StartTime\":\"2024-11-21T12:30:00+01:00\"}"

After SaveAsync:

127.0.0.1:6379> json.get "Player:5c9274f3-e852-4e03-a3b7-424b8679bf99"
"{\"UniquePlayerId\":\"5c9274f3-e852-4e03-a3b7-424b8679bf99\",\"StartTime\":\"2024-11-21T13:30:00+02:00\"}"

I know that I don't have to call SaveAsync after InsertAsync, this is just a minimal example to reproduce the problem.

@slorello89
Copy link
Member

Yeah, it looks like it's regionally adjusting the offset to the TZ based on where Redis OM is running. Trying to think why this would be 🤔 - basically Redis OM takes a snapshot of what your object looks like when it's enumerated (e.g. where you do the FindById) and when you save it, it checks the current state against that snapshot when making its decision about whether or not to commit an update, I guess in this case it must be serializing the new offset to the localized timezone.

@slorello89
Copy link
Member

So I fixed a similar issue a month or so ago, but apparently my fix didn't apply to the Save feature, opened a PR to address.

@Jimmys20
Copy link
Author

Thank you for the quick response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants