3

I am trying to send request from the server to client(.Net) which is running in culture specific environment which affects dates to be in special time zone.

I am sending date from the server with Unspecified kind for avoiding it being converted while getting retrieved on client side. Basically I just convert it like this on server side:

DateTime dateToSend = DateTime.SpecifyKind(serverSideDate, DateTimeKind.Unspecified);

The problem is that when using JsonProtocol for the client, date is not getting converted and is getting processed correctly, while for MessagePackProtocol the same code for client and server side works completely different way - it converts date to culture specific timezone on the client...

How to prevent that conversion, without some hack solutions like passing date as a string.

UPDATE:
As Shaun suggested, I've configured MessagePack both on client and server side this way, but unfortunaly it's still not working:

.AddMessagePackProtocol(options =>
    options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
    {
        StandardResolver.Instance,
        NativeDateTimeResolver.Instance
    })
keuleJ
  • 3,418
  • 4
  • 30
  • 51
Grigoryants Artem
  • 1,401
  • 2
  • 15
  • 32
  • Use `DateTimeOffset`, which includes a timezone component. Then, use something client-side like moment.js which supports localizing dates and times. – Chris Pratt Oct 12 '18 at 14:27
  • I would like to stay with DateTime as far I am passing it to .Net client with models which are used in other places as well – Grigoryants Artem Oct 12 '18 at 14:34
  • 1
    Frankly, if you care about localization at all, you should *always* be using `DateTimeOffset` everywhere. There's actually not a whole lot of good reason to ever use `DateTime` at all in fact. – Chris Pratt Oct 12 '18 at 14:36
  • @GrigoryantsArtem that's even more reason to use DateTimeOffset and avoid unspecified offsets – Panagiotis Kanavos Oct 12 '18 at 14:36

2 Answers2

6

The problem is that kind is lost with the MessagePackProtocol.

DateTime is serialized to MessagePack Timestamp format, it serialize/deserialize UTC and loses Kind info.

The note continues by saying we can change that by using the NativeDateTimeResolver instead (albeit with some limitations).

If you use NativeDateTimeResolver serialized native DateTime binary format and it can keep Kind info but cannot communicate other platforms.

As Chris and Panagiotis mention, it's better to use DateTimeOffset. The official Microsoft documentation says this:

DateTimeOffset should be considered the default date and time type for application development.

There is also much useful information on StackOverflow comparing DateTime vs DateTimeOffset.

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
2

Here the order of resolvers is important. The problem will be solve if NativeDateTimeResolver will be provided before StandardResolver like this.

.AddMessagePackProtocol(options =>
options.FormatterResolvers = new List<MessagePack.IFormatterResolver>()
{
    NativeDateTimeResolver.Instance,
    StandardResolver.Instance        
})
ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
lustoro
  • 21
  • 1