RestSharp 将日期时间转换为 UTC

RestSharp converts Datetimes to UTC

我有以下问题

我正在使用 RestSharp 访问我的 API。但是当我发送 DateTime 时,它​​似乎被转换为 UTC。 我发送 '10.06.1991 00:00' 并且 API 收到 '09.06.1991 22:00'

所以,当我的 API 获得日期时间对象时,我总是需要增加 2 小时?

我检查了 JSON RestSharp 发送到 API。

public class Test
{
    public int IntProperty {get;set;}
    public string StringProperty {get;set;}
    public DateTime DateTimeProperty {get;set;}
}

我的对象是

Test t = new Test{ IntProperty=3, StringProperty="string", DateTimeProperty=new DateTime(1991,06,10) }

当我通过 RestSharp 发送对象时,JSON 我的 API 收到的是

{
    "IntProperty":3,
    "StringProperty":"string",
    "DateTimeProperty":"09.06.1991 22:00:00"
}

知道我能做什么吗? 谢谢

不是你的API收到了错误的数据,而是你的客户端发送了"wrong"数据。我的 API 也遇到了同样的问题。 不,它是正确的数据,但已转换为 UTC。

这里描述了确切的问题:https://github.com/restsharp/RestSharp/issues/834

因此,不要在 API 中为每个 DateTime 添加 2 小时。当另一个客户端发送未转换的日期时,您可能会更改正确的数据。

  1. 您可以检查 GET 上是否收到正确的日期。也许 RestSharp 正在将那个 "wrong" 日期时间转换回 10.06.1991 00:00 - 也许你不介意
  2. 如果您希望数据库不包含 UTC 而包含您最初想要发送的数据,请不要使用默认序列化程序,请使用 JSON.Net (http://www.newtonsoft.com/json)。它不会转换为 UTC 并发送原始 DateTime。

这是一个关于如何实施的非常好的示例:http://bytefish.de/blog/restsharp_custom_json_serializer/

  • 你写了一个自定义 class 来实现 ISerializerIDeserializer
  • 在序列化中调用 JSON.Net Serialize 而在反序列化中调用 JSON.Net Deserialize

  • 你只需要像这样向你的 RestClient 添加一个处理程序:(我正在使用上述博客中描述的静态默认实例)

我的客户看起来像:

private readonly RestClient _client;

public RestApiClient(string apiAdress)
{
    _client = new RestClient(apiAdress);
    _client.AddHandler("application/json", () => NewtonsoftJsonSerializer.Default);
}

并且在请求中您可以设置 JsonSerializer:

 IRestRequest restRequest = 
        new RestRequest(request.GetRestfulUrl(), request.Method) {
            RequestFormat = request.DataFormat, 
            JsonSerializer = NewtonsoftJsonSerializer.Default 
        };

我想这是因为你的 DateTime 对象有 DateTime.Kind 属性 等于 DateTimeKind.Unspecified - 它打破了本地和 utc 类型之间的所有转换。我的意思是有些工具假设你的 DateTime 是 Utc,但实际上不是。

所以不要与那些必须在您和您的客户之间猜测正确类型的 DateTimes 的工具作斗争。只需在任何地方使用 UTC 并转换为本地仅向用户显示。

或者,更好的是,使用 DateTimeOffset which is more suitable to deal with multizone times.. or even use Jon Skeet's NodaTime 库,它是任何与时间相关的工作的瑞士刀(尽管,这对您的情况来说可能有点过分)。

UPD。在下面的评论中回答@Matthias Burger 的问题:

How would you work with dates like date of birth? I think "10.06.1991" could be a birthday. Means, in UTC his birthday were different than GMT - wouldn't it?

一如既往-视情况而定:)

由于时间是一件棘手的事情,您应该小心 - Jon Skeet 的博客中有一篇关于 joys of date/time arithmetic 的精彩文章。老实说,我知道这不是一个真正的答案,但可能存在太多不同的问题案例——我们是否需要比较日期,它们是否在同一日历中,我们是否假设所有人都在当地时区的午夜出生并且等等

在已经提到的NodaTime中有一个全局和局部瞬间的概念(看看它是concepts page)。我认为对于最简单的情况,当我们只需要存储和显示生日 LocalDate(本地日期即时)就足够了。如果您存储本地日期并为所有人固定相同的时区,即使 DateTime 也足够了(这样就好像您根本不使用时区一样)。

P.S。顺便说一句,不知道最后一个问题是不是检查,但是 UTC is a standard and GMT is a time zone ;)