3

I just learned that the JavaScript Date object apparently always stores the local time zone offset. When posting such a date to the server (using $http.post for example) the server gets the UTC date (local date minus time zone offset). That of course is right. In my case the server stores the date in a database.

When getting dates from the server (using $http.get for example) the server sends back the UTC date. If I directly bind these dates to a view the view displays the wrong date (the UTC date). To avoid that I found out that I must write a new Date instance to the model, passing the date I got from the server.

Problem is that this is a lot of work, especially if the server sends a model that actually should be directly bound to the view.

I am looking for a way to avoid having to create Date instances for each date property of models I got from the server in my controllers.

Jürgen Bayer
  • 2,993
  • 3
  • 26
  • 51
  • Which language you use at server side? which platform? – micronyks Aug 21 '14 at 17:18
  • I use .NET with C# and ASP.NET Web API (REST controllers). I store the dates in DateTime objects that do not hold the timezone offset. – Jürgen Bayer Aug 21 '14 at 17:27
  • you can manipulate date at server side using c#. and then return that required/converted date to .js side. (date manipulation is very boring) – micronyks Aug 21 '14 at 17:30
  • Did'nt think about that. That would be a hack, but much easier to program than in JavaScript. Problem is only that I had to know the timezone offset the client uses. Could pass that as an additional parameter. Interesting ... – Jürgen Bayer Aug 21 '14 at 17:38
  • @micronyks: Post that as an answer and I accept it. Works like a charm and solves another problem that I had at the same time :-) – Jürgen Bayer Aug 21 '14 at 17:52
  • 1
    I am guessing you are building an app that there maybe users from different time zones accessing your server simultaneously, and you would want the client receive their respective offset-ed times. Since you are using .NET with C#, I would suggest you use `DateTimeOffset` instead of `DateTime`, of which you will get a representation of instantaneous time. Here is a good read: http://stackoverflow.com/questions/4331189/datetime-vs-datetimeoffset – CozyAzure Aug 21 '14 at 17:53
  • I did not try DateTimeOffset because the database does not support it. Trying it in a small test app I found that it works as expected. The server still gets the UTC date when posted but I do not have to pack dates I got to a new Date to get the local date. – Jürgen Bayer Aug 22 '14 at 05:58

1 Answers1

1

I have created this function that can be ran on the client, which adjusts the date by the current timezone offset. When the adjusted date is sent to the server, the DateTime object parsed from the post data will represent the same (local) date as seen on the client UI:

        adjustDateByTimezoneOffset: function (date) {

            // Javascript Date object stores the local timezone offset.
            // On tranmission to the server the UTC date is sent. The server 
            // may not be timezone aware, and so this function facilitates
            // adjusting to a date which can then be sent to a .NET web application and
            // be recieved as a DateTime instance that equals the current (local) time on 
            // the client.

            if (date && (date instanceof Date)) {

                var timezoneOffsetMinutes = date.getTimezoneOffset();

                var setMinutes = date.getMinutes() - timezoneOffsetMinutes;

                date.setMinutes(setMinutes);
            }
            else {

                throw "Input variable must be Date";
            }

            return date;
        }
gbro3n
  • 6,729
  • 9
  • 59
  • 100
  • Thanks, but that is what I wanted to avoid. I use an AngularJS model that comes from the server and is directly bound to the view. I would need to convert each date of the model after getting it and convert back before sending it. That's the work I wanted to avoid. – Jürgen Bayer Jun 25 '15 at 13:15