RestSharp将日期时间转换为UTC

9

我有以下问题

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

所以,当我的API收到DateTime对象时,我总是需要加上2个小时吗?

我检查了RestSharp发送到API的JSON。

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发送对象时,我的API收到的JSON如下:
{
    "IntProperty":3,
    "StringProperty":"string",
    "DateTimeProperty":"09.06.1991 22:00:00"
}

有什么建议吗?谢谢。


这是否与https://github.com/restsharp/RestSharp/issues/691相同的问题? - mjwills
2个回答

11

不是你的API接收了错误的数据,而是你的客户端发送了“错误”的数据。我的API也遇到了同样的问题。

不,这是正确的数据,只是被转换为UTC。

具体的问题在这里描述:https://github.com/restsharp/RestSharp/issues/834

因此,在你的API中不要添加2小时来处理每个DateTime。当其他客户端发送未转换的日期时,你可能会更改正确的数据。

  1. 你可以检查一下是否在GET请求中收到了正确的日期。也许RestSharp将那个“错误”的日期转换回了10.06.1991 00:00——也许你可以接受它
  2. 如果你不希望数据库包含UTC时间,而是你想要发送的原始数据,请不要使用默认的序列化程序,而要使用JSON.Net (http://www.newtonsoft.com/json)。它不会转换为UTC并发送原始DateTime。

这里有一个非常好的示例说明如何实现:http://bytefish.de/blog/restsharp_custom_json_serializer/

  • 你编写一个自定义类来实现ISerializerIDeserializer
  • 在序列化时调用JSON.Net的Serialize,在反序列化时调用JSON.Net的Deserialize

  • 只需像这样为你的RestClient添加一个处理程序:(我正在使用上述博客中描述的静态Default-instance)

我的客户端看起来像:

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 
        };

request 是什么变量? - its_time_for_weekend
这只是一个包含路径和其他请求API信息的对象而已。没什么特别的。重要的是将JsonSerializer设置为使用Json.Net的那个。 - Matthias Burger
这对我很有帮助,尽管您指定的AddHandler现在已经过时了,改为 _client.AddHandler("application/json", () => NewtonsoftJsonSerializer.Default); - andyb952
对我来说问题是JSON中未指定类型的日期2022-01-02 23:00被设置为DateTime.Kind = UTZ而不是Unspecified。 上述解决方案已不再可用(NewtonsoftJsonSerializer.Default),但现在发现您可以添加nuget RestSharp.Serializers.NewtonsoftJson并使用以下代码设置处理程序: client.UseNewtonsoftJson(); 现在未指定的日期仍然保持未指定状态。 :) - jornhd

2
我猜这是因为您的DateTime对象具有DateTime.Kind属性等于DateTimeKind.Unspecified - 它会中断本地和UTC种类之间的所有转换。我的意思是,某些工具假定您的DateTime在UTC中,当它实际上并不是。所以,不要与必须在您和客户之间猜测DateTimes正确类型的工具进行斗争。只需在所有地方使用UTC,并仅在向用户显示时将其转换为本地时间。

或者,更好的方法是使用DateTimeOffset,它更适合处理多时区时间...或者使用Jon Skeet的NodaTime库,它是任何时间相关工作的瑞士军刀(尽管对于您的情况来说可能有点过头)。

更新。回答下面评论中@Matthias Burger的问题:

如何处理出生日期等日期?我认为“10.06.1991”可能是一个生日。这意味着,在UTC时,他的生日与GMT不同,对吗?
像往常一样 - 这取决于情况 :)
时间是一个棘手的问题,你应该小心 - Jon Skeet的博客有一篇关于日期/时间算术之乐的好文章。老实说,我知道这不是真正的答案,因为存在太多不同的可能性问题 - 我们需要比较日期吗?它们在同一个日历中吗?我们假设所有人都在当地时区的午夜出生等等。
在已经提到的 NodaTime 中,有全局和本地时刻的概念(请参阅其 概念页面)。我认为对于最简单的情况,当我们只需要存储和显示生日时,LocalDate(本地日期时刻)就足够了。即使你存储本地日期并为所有时间固定同一时区,甚至使用 DateTime 也足够了(这样就像你根本没有使用时区一样)。
附言:顺便说一句,不知道最后一个问题是不是一个检查,但 UTC 是一个标准,GMT 是一个时区 ;)

仅供我的兴趣和更好的理解:您如何处理像出生日期这样的日期?我认为“10.06.1991”可能是一个生日。这意味着,在UTC中,他的生日与GMT不同 - 对吗? - Matthias Burger

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