1

I have a system that is used by multiple users and other systems across multiple time zones. I am hosting it on Azure. I want to save all dates in local time, not server time. I am able to do that by keeping track of each customer's local timezone and I am offsetting the dates before saving them in the database.

So far everything works well, however when the dates are sent back to the client's browser MVC thinks they are in UTC (this is the server time for all Azure VMs) and offsets the hours.

What is the most efficient way to prevent this? I tried setting the DateTimeKind to local, but this did not have the desired effect. The dates still got converted. I guess I could pass the dates as strings, but this seems like a hack. There must be a better way to do that.

Your suggestions are highly appreciated.

dpdragnev
  • 2,011
  • 2
  • 28
  • 55
  • If you know your clients timezone in advance then you are going to find it more scalable and easier to adjust and maintain if you convert to UTC saving local dates and convert back to a specific locale when information need to be displayed. It is easier to do date time math when everything is synced to one timezone server side. – Ross Bush Sep 30 '16 at 14:42
  • what if you set the datetimekind to utc? – JamieD77 Sep 30 '16 at 15:34
  • @JamieD77. I did try that, but with no effect. For some reason the dates always get converted. – dpdragnev Sep 30 '16 at 15:54
  • @RossBush: I agree with you, however my scenario is very peculiar. All date/time math have to be done according to the client's local time zone. The actual user might be accessing the app via a mobile device from a different time zone, but the times still have to shown and calculated with respect to the 'home' timzeone. This is the primary reason why I want everything saved and displayed in the local to the client time – dpdragnev Sep 30 '16 at 16:15
  • I think it is the browser that is converting the dates. Normally, the date will come across directly how you read from the database, even if the current threads culture is set to another time zone. When you store the date you expect to retrieve it the way in which it was stored and .NET does not inherently add a conversion unless you specify it. Check the date string being sent across does it have a Z? – Ross Bush Sep 30 '16 at 23:51
  • @RossBush: This is what I am getting back: "/Date(1475231220000)/". If I run moment("/Date(1475231220000").toDate() I get: Fri Sep 30 2016 03:27:00 GMT-0700 (Pacific Daylight Time) when the time should be 10:27:00 (from the database). I check the value right before it gets sent to the client and it is 10:27, so somewhere between the end of the server method and the ajax call complete event on the client the date gets changed. – dpdragnev Oct 01 '16 at 02:56

1 Answers1

2

Ok, so after couple of days of searching and testing I came up with a solution that solves the problem.

On the server:

public JsonResult GetModel()
{
  EOListModel model = _repo.Getmodel();
  return Json(JsonConvert.SerializeObject(model));
}

Couple of points here: - the method returns JsonResult - We serialize the model into a json string

On the client:

$.ajax({
  type: "POST",
  url: "/Controller/GetModel",
  data: null
  }).done(function (result) {
    var m = JSON.parse(result);
    ...
});

result will be your json string and after parsing you will get your object with the dates intact.

I am not positive this is the best way to achieve this, but it works and has a minimal amount of code changes.

Thanks.

EDIT:

In the server method you also need to instruct JSON.NET not to append the timezone:

return Json(JsonConvert.SerializeObject(model, new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.Unspecified }));

Otherwise Javascript or Moment will convert the date. See http://www.newtonsoft.com/json/help/html/SerializeDateTimeZoneHandling.htm for more details.

dpdragnev
  • 2,011
  • 2
  • 28
  • 55
  • 1
    Good answer. I do want to point out that returning Json(JsonConvert.SerializeObject( double serializes the json data, and that is why you have to use JSON.parse(result) in the client code. Some may consider it cleaner to use ActionResult instead of JsonResult and then return Content(JsonConvert.SerializeObject( this would allow you to do away with the JSON.parse entirely – josgall May 06 '20 at 01:02
  • see my answer to a related question [here](https://stackoverflow.com/questions/3332498/json-returns-different-dates-when-local-machine-and-server-in-different-timezone/61625809#61625809) – josgall May 06 '20 at 01:31