0

I tried the following code

var parts ='2014-04-03'.split('-');
    // Please pay attention to the month (parts[1]); JavaScript counts months from 0:
    // January - 0, February - 1, etc.
    var mydate = new Date(+parts[0], +parts[1] - 1, +parts[2]); 
    console.log(mydate);

However, the result is

2014-04-02T17:00:00:000Z

I wonder why the result is not 2014-04-03

Thanks

Nikos M.
  • 8,033
  • 4
  • 36
  • 43
Jond
  • 57
  • 1
  • 11
  • 1
    "By default, JavaScript will use the browser's time zone and display a date as a full text string" from https://www.w3schools.com/js/js_dates.asp – Fabien Greard Dec 18 '18 at 09:01
  • Because the values are treated as local. If you want UTC, use `new Date(Date.UTC(...))`. – RobG Dec 18 '18 at 09:06
  • @FabienGreard—that isn't necessarily correct as the OP shows. Please don't reference w3schools, ECMA-262 and MDN are better. :-) – RobG Dec 18 '18 at 09:30
  • @RobG I don't like w3schools either as a source of truth, however I like the way they simplify things – Fabien Greard Dec 18 '18 at 09:35

3 Answers3

1

Beware, javascript can sneak in the local timezone both when you create a date, and when you serialize it. The code shown, new Date(int,int,int), creates a date object representing local midnight for the year/month/day specified.

YYYY-MM-DD dates can be parsed exactly as they are. Just do new Date('2014-04-03'). This gives you a midnight UTC date object which is exactly what you want.

Then you need to be a bit careful with the methods used when formatting (serializing), more details at the link above.

var myDate = new Date('2014-04-03')
console.log(myDate.toLocaleDateString("fr",{timezone:"UTC"}))
bbsimonbb
  • 27,056
  • 15
  • 80
  • 110
0

You can use one Javascript function to convert date to required 'yyyy-MM-dd' format. Below is code snippet.

function DateToStr(date, format) {
  let z = {
    y: date.getFullYear(),
    M: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    m: date.getMinutes(),
    s: date.getSeconds()
  };
  return format.replace(/(y+|M+|d+|h+|m+|s+)/g, v => ('0' + z[v.slice(-1)]).slice(-v.length));
}

var parts = '2014-04-03'.split('-');
var mydate = new Date(parts[0], parts[1] - 1, parts[2]);
var a = DateToStr(mydate, 'yyyy-MM-dd')

console.log(a);
RobG
  • 142,382
  • 31
  • 172
  • 209
  • 1
    This doesn't answer the question. Any solution using *eval* needs a seriously good reason to do so. Using it for a simple parser is totally unnecessary. `new Date(mydate)` is redundant, it just creates a new Date that has an identical time value to the original. When passing more than one parameter, using *parseInt* is redundant as the [*Date* constructor](http://ecma-international.org/ecma-262/9.0/#sec-date-year-month-date-hours-minutes-seconds-ms) calls [*ToNumber*](http://ecma-international.org/ecma-262/9.0/#sec-tonumber) on each argument. – RobG Dec 18 '18 at 10:00
  • Hi RobG, You are right about using parseInt() into my code. I have updated my code. Please look into it. It will provide you required output now. Thanks – Nirav Patel Dec 18 '18 at 10:05
0

Use Date.UTC as it treats dates in UTC format discarding local timezone and daylight saving time.

var parts ='2014-04-03'.split('-');
// Please pay attention to the month (parts[1]); JavaScript counts months from 0:
// January - 0, February - 1, etc.
var mydate = new Date(Date.UTC(+parts[0], +parts[1] - 1, +parts[2])); 
console.log(mydate);
Nikos M.
  • 8,033
  • 4
  • 36
  • 43
  • Wow. `new Date(Date.UTC(parts[0], parts[1]-1, parts[2]))` is all that's required, the `charAt` stuff is remarkable convolution and completely unnecessary. ;-) – RobG Dec 18 '18 at 10:12
  • @RobG, I added it so as to be correctly transformed to int as it might contain `"0"` characters in start of string. But one may not use it. I think it is better to handle it explicitly – Nikos M. Dec 18 '18 at 10:26
  • 1
    Leading zeros were an issue with *parseInt* in some implementations compliant with ECMA-262 ed 3 (1999). This code doesn't use *parseInt* and if it did, using a radix of 10 avoids it, explicitly. The internal conversion to number using *ToNumber* also explicitly addresses the conversion issue, as does the use of unary + (which is redundant), both of which always use a radix of 10. If you want to manually handle the conversion, you should check the result before using it, otherwise the manual conversion is pointless. – RobG Dec 18 '18 at 10:42
  • @RobG, I agree, you are correct. But better safe than sorry. personaly I prefer to ahndle explicitly for a number of reasons. One being that I am not sure what will the platform the code is going to be executed. But as I said, one can skip this step. it is my personal style to handle explicitly if uncertain – Nikos M. Dec 18 '18 at 10:47