Skip to content

Cosmos DB: DateTime serialization format causing errors in ordering and filtering #39113

Description

@Henri-Wiechers

Bug description

DateTimes are serialized to ISO8601 dates but the trailing zeros are dropped in the second fractions. The means that the lexicographic ordering of the values doesn't match the correct ordering. This causes errors in ordering and filtering.

Related Azure/azure-cosmos-dotnet-v3#4904

Your code

using Microsoft.EntityFrameworkCore;

var endpoint = Environment.GetEnvironmentVariable("COSMOS_ENDPOINT")
    ?? throw new InvalidOperationException("COSMOS_ENDPOINT is not set.");

var key = Environment.GetEnvironmentVariable("COSMOS_KEY")
    ?? throw new InvalidOperationException("COSMOS_KEY is not set.");

var databaseName =
    Environment.GetEnvironmentVariable("COSMOS_DATABASE")
    ?? "EfCoreDateTimeRepro";

var options = new DbContextOptionsBuilder<TestDbContext>()
    .UseCosmos(endpoint, key, databaseName)
    .EnableSensitiveDataLogging()
    .LogTo(Console.WriteLine)
    .Options;

await using var db = new TestDbContext(options);

await db.Database.EnsureCreatedAsync();

if (await db.Items.CountAsync() == 0)
{
    db.Items.AddRange(
        new TestItem
        {
            Id = "exact-second",
            Timestamp = new DateTime(
                2026, 1, 1, 0, 0, 0,
                DateTimeKind.Utc)
        },
        new TestItem
        {
            Id = "fractional-second",
            Timestamp = new DateTime(
                2026, 1, 1, 0, 0, 0, 123,
                DateTimeKind.Utc)
        });

    await db.SaveChangesAsync();
}

// The result of the inserts are these docs. Note that the timestamps have a different
// number of decimal digits.

// {
//     "id": "exact-second",
//     "$type": "TestItem",
//     "Timestamp": "2026-01-01T00:00:00Z",
//     "_rid": "fedHAL39aMkBAAAAAAAAAA==",
//     "_self": "dbs/fedHAA==/colls/fedHAL39aMk=/docs/fedHAL39aMkBAAAAAAAAAA==/",
//     "_etag": "\"02009396-0000-3000-0000-6aba61850000\"",
//     "_attachments": "attachments/",
//     "_ts": 1790599557
// }
// {
//     "id": "fractional-second",
//     "$type": "TestItem",
//     "Timestamp": "2026-01-01T00:00:00.123Z",
//     "_rid": "fedHAL39aMkCAAAAAAAAAA==",
//     "_self": "dbs/fedHAA==/colls/fedHAL39aMk=/docs/fedHAL39aMkCAAAAAAAAAA==/",
//     "_etag": "\"02009496-0000-3000-0000-6aba61850000\"",
//     "_attachments": "attachments/",
//     "_ts": 1790599557
// }


// Problem 1: Incorrect ordering.

var all = await db.Items.OrderBy(x => x.Timestamp).ToListAsync();

Console.WriteLine(string.Join(",", all.Select(x => x.Id)));

// `all` is ['fractional-second', `exact-second`]
// The order is wrong because "2026-01-01T00:00:00Z" > "2026-01-01T00:00:00.123Z".


// Problem 2: Incorrect filtering

var boundary = new DateTime(
    2026, 1, 1, 0, 0, 0,
    DateTimeKind.Utc);

var results = await db.Items
    .Where(x => x.Timestamp > boundary)
    .OrderBy(x => x.Timestamp)
    .ToListAsync();

Console.WriteLine(results.Count);

// Results is empty but it should contain "fractional-second".
// It doesn't because boundary is serialized to "2026-01-01T00:00:00Z"
// and "2026-01-01T00:00:00Z" > "2026-01-01T00:00:00.123Z".

// info: 2026/09/28 14:51:26.494 CosmosEventId.ExecutedReadNext[30102] (Microsoft.EntityFrameworkCore.Database.Command)
//       Executed ReadNext (349.2587 ms, 2.79 RU) ActivityId='a336e1d3-fe82-4e90-b053-7166421065f9', Container='Items', Partition='None', Parameters=[@boundary='2026-01-01T00:00:00Z']
//       SELECT VALUE c
//       FROM root c
//       WHERE (c["Timestamp"] > @boundary)
//       ORDER BY c["Timestamp"]


public sealed class TestDbContext(DbContextOptions<TestDbContext> options)
    : DbContext(options)
{
    public DbSet<TestItem> Items => Set<TestItem>();

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<TestItem>(entity =>
        {
            entity.ToContainer("Items");
            entity.HasKey(x => x.Id);
            entity.HasPartitionKey(x => x.Id);
        });
    }
}

public sealed class TestItem
{
    public string Id { get; set; } = null!;

    public DateTime Timestamp { get; set; }
}

Stack traces


Verbose output


EF Core version

10.0.12

Database provider

Microsoft.EntityFrameworkCore.Cosmos

Target framework

.NET 10.0

Operating system

Windows 11

IDE

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions