Thoth.Json icon indicating copy to clipboard operation
Thoth.Json copied to clipboard

On serializing/deserializing a DateTime, "Kind" information is lost and is set to UTC

Open MangelMaxime opened this issue 5 years ago • 4 comments

Issue by sachabroute Thursday Jul 25, 2019 at 11:00 GMT Originally opened as https://github.com/MangelMaxime/Thoth/issues/156


When serializing a DateTime CEST, on deserializing we lose the "Kind" information and it is set by default to UTC.

Client: image

Server: image

MangelMaxime avatar Nov 08 '19 14:11 MangelMaxime

Comment by MangelMaxime Thursday Jul 25, 2019 at 11:16 GMT


By default, we transfer UTC over the JSON because your client and server can be on a different timezone. I think this is what most JSON serialize do but can be wrong.

In general, if you need a specific DateTime handler, you should write your own.

It's also possible that DateTimeOffset is a solution for that too, I don't know. Handling date is really complex :)

MangelMaxime avatar Nov 08 '19 14:11 MangelMaxime

Comment by sachabroute Thursday Jul 25, 2019 at 11:51 GMT


Makes sense, I was also thinking it might have been done deliberately as server should always have the UTC time. However it seems there is some ambiguity as to other JSON serializers do since I think Newtonsoft.Json does deserialize the Kind properly, but Microsoft's don't. Maybe this could deserve some kind of note somewhere?

MangelMaxime avatar Nov 08 '19 14:11 MangelMaxime

Comment by MangelMaxime Thursday Jul 25, 2019 at 11:54 GMT


Maybe this could deserve some kind of note somewhere?

We can add that to the doc comment here and here.

Note that the projects are in a separate repo.

The split of this repo isn't complete yet.

MangelMaxime avatar Nov 08 '19 14:11 MangelMaxime

Thoth.Json should not assume that the DateTime sent from server should always be in UTC. There are many cases where local DateTime will be sent (like alarm time).

Unless the server sends timestamp with the Z specifier (ex. 2021-03-03T09:30:00Z) or with the timezone difference (ex. 2021-03-03T09:30:00−02:00), Thoth.Json should return the DateTime with Kind set to Unspecified. IMO, this is the correct behavior.

.NET and Fable already behaves as expected.

    DateTime.Parse("2021-03-03T09:30:00")     // DateTime.Kind is Unspecified
    DateTime.Parse("2021-03-03T09:30:00Z")    // DateTime.Kind is Local

However in Decode.fs

let datetime : Decoder<System.DateTime> =
    fun path value ->
         if Helpers.isString value then
             match System.DateTime.TryParse (Helpers.asString value) with
             | true, x -> x.ToUniversalTime() |> Ok
             | _ -> (path, BadPrimitive("a datetime", value)) |> Error

there's conversion x.ToUniversalTime(). Is this conversion required when the user did not ask for it?

I'm not sure what's the motive of doing this conversion so I may be wrong too.

nirvinm avatar Mar 20 '21 11:03 nirvinm

In PR #149, we the Decode.datetime as being marked as obsolete to make it explicit was is happening to the date.

I think this also fix the issue too.

MangelMaxime avatar Nov 09 '22 19:11 MangelMaxime