CosmosDB - UTC查询中的DateTimeOffset问题

3
在使用CosmosDb中涉及DateTimeOffset存在问题。根据Microsoft文档中的指南(链接),需要将本地DateTime转换为UTC时间,则必须将偏移量存储为JSON属性,并让客户端使用该偏移量来计算UTC DateTime值。
我将日期存储在文档中,格式为“2021-04-23T12:15:00+01:00”。这在本地查询和显示用户时非常有效。但是,在对这些DateTimes执行查询时会遇到问题...
在服务器上执行查询如下:
.Where(x => x.ExpiresAt.UtcDateTime <= DateTime.UtcNow)

如果expiresAt = "2021-04-23T12:15:00+01:00"
而且现在的UTC时间 = "2021-04-23T11:15:00+00:00"
我希望查询返回一个项目。然而,在一个小时之后才返回任何项目,就好像.UtcDateTime扩展不起作用一样。
如果是这样的话,你如何比较这样的DateTimeOffsets呢?Microsoft文档让人觉得你需要另一个字段来存储偏移量,并且不能直接与datetime本身一起使用。比如...
{
    "expiresAt":"2021-04-23T11:15:00",
    "expiresAtOffset":"1"
}  

我肯定是误解了,对吧?

注意:我尝试使用SQL查询代替linq,代码如下...

"SELECT * FROM c WHERE c.expiresAt <= \"2021-04-23T11:58:05\""

但问题依旧存在,因为问题在于cosmos值需要转换和查看文档中没有将cosmos值转换为UTC时间的方法...


不是答案,但可以看一下MongoDB处理这个问题的各种方法:https://blog.krusen.dk/c-mongodb-serialization-of-datetimeoffset/。对于查询,您需要使用UTC,但对于显示,您确实希望知道记录时的偏移量。 - Ian Mercer
2个回答

1

另一个StackOverflow 上的问题建议使用 Z 缩写进行存储。我尝试了一下,它似乎大致符合我的要求,但不完美。所有日期现在都以 DateTime 值存储,并附加 Z。然后使用 DateTimeOffset DTO,在客户端上将适当地转换该值。但必须更改序列化设置,如下所示...

   var jsonSerializerSettings = new JsonSerializerSettings
        {
            DateFormatHandling = DateFormatHandling.IsoDateFormat,
            DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffZ"
        };

然后我补充说,在创建DocumentClient时...
new DocumentClient(serviceEndpoint, authKey, serializerSettings: jsonSerializerSettings);

我唯一的问题是,我有一些需要从服务器发送的电子邮件,其中包含时间。由于服务器不知道如何将它们转换为客户端的本地时间,所以这些时间是不正确的。

0

根据我的经验,在.NET上实现与宇宙和日期时间相关的幸福感,以下组合是行之有效的:

  • 将日期和时间模型化为 ISO 8601 值,建议参考 文档
  • 使用 DateTime .NET 类型,而不是 DateTimeOffset
  • 确保完整的日期时间以精确格式 yyyy-MM-ddTHH:mm:ss.fffffffZ 进行序列化
  • 始终存储 UTC 值,而不是本地时间
  • 如果值表示发生在特定时区的事件,请将 IANA 时区 存储在该值旁边。然后在向用户显示之前使用它进行转换。
  • 在 .NET SDK 3 中使用基于流的方法 (示例) 和 System.Text.Json 来直接控制序列化,并获得预期的默认效果
  • 避免使用 LINQ,而是使用 QueryDefinition 从字符串构建查询

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接