I have following problem
I'm using RestSharp for accessing my API. But when I'm sending a DateTime it seems to be converted to UTC. I'm sending '10.06.1991 00:00' and the API gets '09.06.1991 22:00'
So, I would always need to add 2 hours when my API gets a DateTime-object?
I checked the JSON RestSharp sends to the API.
public class Test
{
public int IntProperty {get;set;}
public string StringProperty {get;set;}
public DateTime DateTimeProperty {get;set;}
}
My object is
Test t = new Test{ IntProperty=3, StringProperty="string", DateTimeProperty=new DateTime(1991,06,10) }
when I'm sending the object via RestSharp, the JSON my API receives is
{
"IntProperty":3,
"StringProperty":"string",
"DateTimeProperty":"09.06.1991 22:00:00"
}
Any idea what I could do? Thanks
It's not your API that receives wrong data, it's your client that sends "wrong" data. I got the same problem with my API. No, it's correct data but converted to UTC.
The exact problem is described here: https://github.com/restsharp/RestSharp/issues/834
So, don't add 2 hours to each DateTime you get it in your API. You would perhaps change correct data when another client sends unconverted dates.
10.06.1991 00:00
- maybe you are okay with itHere is one really good example on how to implement: http://bytefish.de/blog/restsharp_custom_json_serializer/
ISerializer
and IDeserializer
in serialize you call JSON.Net Serialize
while in deserialize you call JSON.Net Deserialize
you just need to add a handler to your RestClient like this: (I'm using the static Default-instance described in the mentioned blog)
my client looks like:
private readonly RestClient _client;
public RestApiClient(string apiAdress)
{
_client = new RestClient(apiAdress);
_client.AddHandler("application/json", () => NewtonsoftJsonSerializer.Default);
}
and in requests you can set the JsonSerializer
:
IRestRequest restRequest =
new RestRequest(request.GetRestfulUrl(), request.Method) {
RequestFormat = request.DataFormat,
JsonSerializer = NewtonsoftJsonSerializer.Default
};
I guess it's because your DateTime
objects have DateTime.Kind
property equals to DateTimeKind.Unspecified
- it breaks all conversions between local and utc kinds. I mean some tool assumes that your DateTime is in Utc when it isn't really.
So just don't fight with the tools which have to guess the right kind of your DateTimes in the middle between you and your client. Just use UTC everywhere and convert to local only to show it to user.
Or, even better, use DateTimeOffset which is more suitable to deal with multizone times.. or even use Jon Skeet's NodaTime library which is a swiss knife for any time-related work (although, maybe it's an overkill for your case).
UPD. To answer the question from @Matthias Burger in comments below:
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?
As always - it depends :)
As time is a tricky thing, you should be careful - and there is a great article from the Jon Skeet's blog about joys of date/time arithmetic. I know it's not a real answer, honestly, but there're too much different possible problem cases - do we need to compare dates, are they in the same calendar, do we assume that all people were born at midnight in local time zone and etc.
In already mentioned NodaTime
there's a concept of global and local instants (look at it's concepts page). I think for the most simple cases when we need to just store and show birthdays LocalDate
(local date instant) is enough. Even DateTime
is enough if you store local date and fixate the same time zone for all (so it'll be like you don't use time zone at all).
P.S. Btw, don't know if the last question was a check or not, but UTC is a standard and GMT is a time zone ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With