1

I am making an AJAX request like the following:

$.ajax({
    type: 'POST',
    url: '@Url.Action("GetExpirationDates", "Products")',
    data: data,
    dataType: 'json',
    success: function (data) {
    var dateArray = data.map(function (date) {
        var d = new Date(date);
        return d.toLocaleDateString();
    });
});

Here is what data looks likes:

2016-02-25T00:00:00,2016-03-25T00:00:00,2016-04-25T00:00:00

It seems that as soon as I do new Date(date) each one of these dates has a chance of showing as

2/24/2016, 3/24/2016, 4/24/2016

(one day less than it should be) depending on what the local time is. I am aware that this is most likely due to the way JavaScript handles timezones. I am wondering how to go about fixing it.

Blake Rivell
  • 13,105
  • 31
  • 115
  • 231
  • 1
    I recommend [moment.js](http://momentjs.com/) to more easily deal with dates. The timezone issues and many other things are much more gracefully handled. Another hack would be to add 12 hours to each Date. – ryanyuyu Feb 23 '16 at 14:07
  • +1 for moment.js. Also read up on UTC datetime handling to help avid all sorts of complexity. http://stackoverflow.com/questions/9756120/how-do-i-get-a-utc-timestamp-in-javascript https://en.wikipedia.org/wiki/Coordinated_Universal_Time – Murray Foxcroft Feb 23 '16 at 14:11

3 Answers3

3

It depends on how you want to consume the end result. A simple example is:

var d = new Date("2016-02-25T00:00:00");
d.getDate(); //returns 24 because my timezone is -06:00.
d.getUTCDate(); //returns 25, the UTC day of the month

The same can be done for getMonth/getUTCMonth

I would really suggest using moment. Where its as easy as

moment("2016-02-25T00:00:00").format("MM/DD/YYYY"); //returns "02/25/2016"

It gives you finer control over UTC and formatting strings.

comwizz2
  • 106
  • 1
  • 11
  • So how can I go from: var d = new Date("2016-02-25T00:00:00"); to a formatted date string of "2/25/2016"? – Blake Rivell Feb 23 '16 at 15:10
  • I came down to me doing the following: Is this really what has to be done? (d.getMonth() + 1) + '/' + d.getUTCDate() + '/' + d.getFullYear() – Blake Rivell Feb 23 '16 at 15:17
  • Javascript doesn't really have a format function for string. Also if using toUTCDate make sure you use toUTCMonth and toUTCFullYear or your month/year could be off on days near month end/start. I really recomment using Moment.js if you want to work with dates much. http://momentjs.com/ – comwizz2 Feb 23 '16 at 15:35
  • If i use moment.js is it really that easy to always display dates in the proper time zone? What function would I use in my case? – Blake Rivell Feb 23 '16 at 15:39
  • Added example to my answer! – comwizz2 Feb 23 '16 at 15:49
  • That worked perfectly. Moment automatically handles this problem? Is the moment-with-locale required for this functionality or can I just use the standard moment – Blake Rivell Feb 23 '16 at 15:53
  • Locales is just for non-english display strings I believe. What I did was with base moment library. I would highly recommend scanning their docs just to familiarize yourself with what its capable of. – comwizz2 Feb 23 '16 at 16:05
  • 1
    Whats happening here is that in the absence of a timezone, moment is treating that string as localtime, not utc. So formatting it out the date stays the same. – comwizz2 Feb 23 '16 at 16:07
0

Give this a shot:

function getNow() {
    var date = new Date(),
        y = date.getFullYear(),
        mo = date.getMonth() + 1,
        d  = date.getDate(),
        h = date.getHours(),
        m  = date.getMinutes(),
        s  = date.getSeconds();

    date.setDate(date.getDate());
    mo = (mo < 10 ? '0' : '') +  mo;
    d = (d < 10 ? '0' : '') + d;
    h = (h < 10 ? '0' : '') + h;
    m = (m < 10 ? '0' : '') + m;
    s = (s < 10 ? '0' : '') + s;

    return h + ':' + m + ':' + s + ' - ' + mo + '/' + d + '/' + y;
}
iSkore
  • 7,394
  • 3
  • 34
  • 59
0

If you do not specify a UTC offset when using ISO8601 date strings, the browser will assume that the date is UTC.

Representing this as a locale date string will apply the offset according to your timezone.

If you want to get the UTC date, you can use

return d.toUTCString();

Alternatively, if you have control over the JSON service, you can specify a timezone which the dates belong to in the ISO string.

For example, UTC - 7 hours would be represented as.

2016-02-25T00:00:00-0700,2016-03-25T00:00:00-0700,2016-04-25T00:00:00-0700

If your local timezone is UTC - 7 hours, d.toLocaleString would correctly show as

2/25/2016, 3/25/2016, 4/25/2016

jbell
  • 141
  • 3
  • I find it best to let the service always return and accept UTC dates. Let the client javascript do the convertion of times to local time zones and back to UTC. – Jason Williams Feb 23 '16 at 14:34
  • So how can I get the local date string in the format like 2/23/2016? Would it be something like new Date(date.toLocaleString()); ? – Blake Rivell Feb 23 '16 at 14:49