Fable.Remoting icon indicating copy to clipboard operation
Fable.Remoting copied to clipboard

Serialization of DateTime loses Kind and TimeZone

Open MikaelUmaN opened this issue 3 years ago • 5 comments

Hi.

This should be related to: https://github.com/Zaid-Ajaj/Fable.SimpleJson/pull/21 and https://github.com/Zaid-Ajaj/Fable.Remoting/issues/108

Setup

  • dotnet new SAFE
  • Create API accepting DateTime parameter
  • From client, call server api with DateTime.Today (or DateTime.UtcNow.Date, ...)

Expected

  • DateTime instance is the same on client and server.

Actual

  • DateTime on client can be Kind=UTC (or Unspecified) but is always Local on the server.
  • DateTime has Time component 00:00 (because we explicitly use the Date part), but when deserializing it becomes e.g. 2021-10-11 22:00 in my container.

Why this is a problem for me Basically I am on dotnet 5 and eagerly awaiting the "DateOnly" struct.

As it is now, I expect to be able to send string(myDateParameter) to an external http API on the server-side but instead of todays date (e.g. 2021-10-12) I get yesterdays.

Suggestions Probably it's not possible to keep the "Kind" type across serialisation, but then I think it should explicitly call "ToUniversalTime" prior to serialization and explicitly read it as Kind=UTC on the server side when deserializing.

The the application layer can handle the rest.

MikaelUmaN avatar Oct 12 '21 16:10 MikaelUmaN

Hi @MikaelUmaN,

In order not to lose the time zone information it is recommended to use DateTimeOffset which preserves the timezone offset of the server and propagates it to the client (that is represented by Date).

As for the Kind, I believe we had that implemented before but I need to double check

Zaid-Ajaj avatar Oct 12 '21 17:10 Zaid-Ajaj

Hi. Thanks for feedback.

I can confirm that DateTimeOffset works as expected, except it loses "kind" information. It is set to Unspecified.

I still think it would be nice to have DateTime working as well, though. Note that I am just trying to pass dates and not actually times; so it's doubly confusing that the server-side receives another date when transferring a DateTime.

The cleanest solution I think is to do it the way MessagePack does it; and just always rely on UTC when transferring; for example by going to ToUniversalTime and using Ticks.

From my side I will use DateTimeOffset as a workaround until DateOnly arrives in net 6.0 GA. Thanks for an excellent library.

MikaelUmaN avatar Oct 14 '21 07:10 MikaelUmaN

DateTimeOffset does not have any explicit Kind. If the offset is 0, you know it's UTC. Otherwise it's local.

until DateOnly arrives in net 6.0 GA

Yes, I'm looking forward to it too. However, it needs to be supported by Fable as well, and only then can it be implemented in SimpleJson and MsgPack.

kerams avatar Oct 14 '21 08:10 kerams

Yes you are right of course, it does not have Kind. Sorry my mistake, it was because I converted it myself and looked at it.

The comment on DateTime still stands though. However, for my purposes you can close this issue in case it's not prioritized to fix.

MikaelUmaN avatar Oct 22 '21 08:10 MikaelUmaN

I think we can resolve this issue by documenting the current behavior and recommending people to use DateTimeOffset when the timezone is relevant

Zaid-Ajaj avatar Oct 29 '21 09:10 Zaid-Ajaj