0

I am trying to convert the http request data to the correct date format I need.

My http request data from an company returns data like

2015-03-11, 2015-05-13, 2015-11-21...etc.

My codes.

var day1 = '2015-03-11'; //return from http request
var day2 = '2015-05-13'; //return from http request

var date = new Date(day1) -> 
//time will be off 1 day for some reason 
//because javascript can't recognize 03 and it is a string.`

I need to be able to convert 2015-03-11 to March, 11, 2015. Is there any correct ways to fix this issue?

Thanks so much!

FlyingCat
  • 14,036
  • 36
  • 119
  • 198

3 Answers3

5

The problem stems from the fact that JavaScript Date instances include a time-of-day portion, and from the related fact that ISO dates like yours are interpreted as being UTC. If you're west of Western Europe, then, your computer is in a time zone that makes UTC midnight of March 11 2015 be some time in March 10 2015 in your time zone.

There are a couple ways to solve this; here's one:

var utcdate = new Date("2015-03-11");
var local = new Date(utcdate.getUTCFullYear(), utcdate.getUTCMonth(), utcdate.getUTCDate());

That'll make the "local" date be the same as the original date string indicated.

As mentioned in the answer for the linked duplicate question, you can also manipulate the date string before instantiating the date. The best thing would be to make sure your server is producing well-formatted dates.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Thanks! Is there anyway to convert 3 to march too? +1 – FlyingCat Mar 26 '15 at 19:19
  • @FlyingCat I'm not sure what you mean; you can get the month part of a date from the `.getMonth()` API, and then use a lookup table. Note that JavaScript numbers months from 0, not 1, though it parses them as we write them. Thus a date in March returns 2 from `.getMonth()`. – Pointy Mar 26 '15 at 19:21
  • Why does new `Date("2015-3-11");` provide the correct date then? I think I am missing where the "0" comes into play. – KJ Price Mar 26 '15 at 19:24
  • @KJPrice it's browser-dependent; that's not really a valid ISO string - the spec demands that month and day-of-month both be two digits long. Firefox refuses to parse that, but Chrome might accept it. – Pointy Mar 26 '15 at 19:25
  • @Pointy - Sorry to downvote. This approach is common, but is flawed. It shifts the internal time value to a different point in time (by the amount of the tz offset). It will work in the *general* case, but will fail near DST transitions in the local time zone. The correct approach is to manipulate the original value such that it does get parsed as local time instead of UTC. See the answer in the dup link for code. Thanks. – Matt Johnson-Pint Mar 26 '15 at 19:36
  • @MattJohnson true; that's why I said there are multiple ways to do it. I support the closing as a dup - I looked for a little while because it's obviously something asked before, but I didn't find a good one. – Pointy Mar 26 '15 at 19:39
  • @MattJohnson however I don't agree that this will be wrong; functionally it does exactly the same thing as altering the original string to force that date to be created in the local time zone. This does that too. Since the ISO date is parsed as midnight on the given date, the `.getUTCFoo()` methods will return the same values as are in the input string. The method in my answer does not involve *shifting* the original parsed date; the code creates a completely new date using the 3-parameter constructor, which defaults to the local time zone. – Pointy Mar 26 '15 at 19:47
  • Actually, in this particular case, I think you are correct. The reason being that only the year, month, and day are passed. If the time was passed as well, *then* you'd encounter the issue I was mentioning. But since the time isn't passed in, then midnight of the local zone will apply. Sorry about that! Tweak the answer slightly so I can remove the downvote please. :) – Matt Johnson-Pint Mar 26 '15 at 20:45
  • @MattJohnson ha ha - done. The whole Date parsing thing in JavaScript is one of the few situations in which I think it's good to suggest add-on facilities like Moment or DateJS. – Pointy Mar 26 '15 at 21:43
  • @MattJohnson also I've seen an approach that involves adding `.timezoneOffset()` to the minute value (and I even mentioned it in another comment), and that seems like it might cause some weird problems like you describe. – Pointy Mar 26 '15 at 21:48
1

Revised to replace dashes with slashes for ISO formatting:

var day1 = '2015-03-31'; //return from http request
var day2 = '2015-05-13'; //return from http request

function getDateFormat(day)
{
    var date = new Date(day.replace(/-/g, '/'));

    var monthNames = ["January", "February", "March", "April", "May", "June",
      "July", "August", "September", "October", "November", "December"
    ];

    var dateString = monthNames[date.getMonth()] + " " + date.getDate() + ", " + date.getFullYear();

    alert(dateString);//just to test
}

getDateFormat(day1);
getDateFormat(day2);

If all you want is to show the name of the month, day and year, then this will do the trick.

Updated to put it in a function.

sbatson5
  • 648
  • 11
  • 19
0

How about removing that extra "0"?

var date = new Date(day1.replace('-0', '-'));
KJ Price
  • 5,774
  • 3
  • 21
  • 34