8

I need to generate a javascript Date from a UTC date string with the format YYYY-MM-DD. Here is an example:

var date = new Date('2018-01-31');

The date this creates is:

Tue Jan 30 2018 19:00:00 GMT-0500 (Eastern Standard Time)

Given the time zone offset, the date is yesterday.

How can I create a javascript Date that assumes the timeless input is UTC?

mellis481
  • 4,332
  • 12
  • 71
  • 118
  • You can use https://momentjs.com/ and https://momentjs.com/timezone/ is easy to use – Jorge Mejia Jan 31 '18 at 21:21
  • Unless you manipulate the prototype (not suggested), you can't force the Date object into the timezone you want without an if statement. You could do something like `if(!timezone) date = Date.UTC('2018-01-31');` and then `new Date`, but I believe .UTC doesn't accept strings – Sterling Archer Jan 31 '18 at 21:23

2 Answers2

4

You can use Date.UTC .
This is an example from https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC

var utcDate1 = new Date(Date.UTC(96, 1, 2, 3, 4, 5));
var utcDate2 = new Date(Date.UTC(0, 0, 0, 0, 0, 0));

console.log(utcDate1.toUTCString());
// expected output: Fri, 02 Feb 1996 03:04:05 GMT

console.log(utcDate2.toUTCString());
// expected output: Sun, 31 Dec 1899 00:00:00 GMT

So you get this as solution:

var test = "2018-01-31";
var year = test.substr(0,4);
var month =  test.substr(5,2) -1;
var day =  test.substr(8,2);

var utcDate1 = new Date(Date.UTC(year,month,day));
alert(utcDate1.toUTCString());
// expected output:Wed, 31 Jan 2018 00:00:00 GMT
Sascha
  • 4,576
  • 3
  • 13
  • 34
  • Might want to add a source and a quote since that's from the docs directly – Sterling Archer Jan 31 '18 at 21:25
  • This is actually a solution I thought about but I couldn't believe there wasn't something more elegant that took less than 5 lines of code. – mellis481 Jan 31 '18 at 21:45
  • You could write it just in 1 line: var utcDate1 = new Date(Date.UTC(test.substr(0,4),test.substr(5,2)-1,test.substr(8,2))); – Sascha Jan 31 '18 at 21:55
  • 1
    Don't be tempted to write obfuscated code for the sake of brevity. Clear, concise code is much better from a maintainability perspective. You could do `new Date(Date.UTC(...(test.split('-').map((n,i)=>n-i%2))))` but that isn't particularly helpful. ;-) – RobG Jan 31 '18 at 22:57
  • This does not return a UTC `Date` object, it returns a string. `utcDate1` is still a local date. – mellis481 Feb 01 '18 at 14:28
2

You can use a combination of Date.UTC, split and the spread operator syntax (... is not an operator):

var convertedDate = '2018-01-31'.split('-');
convertedDate[1] = convertedDate[1] - 1 // Date.UTC expects a value from 0-11

var date = new Date(Date.UTC(...convertedDate))
console.log(date.toDateString());

It is important to note that Date.UTC expects a month form 0-11 (for some reason)

Zze
  • 18,229
  • 13
  • 85
  • 118
  • 1
    I think your answer is a little bit more compact and technical better than mine. Even my is a perhaps a little bit more intuitive. The spread operator is nice, I didn't know about it till know. The only thing is the op wants dateUTC so date.toUTCString is the better output but this is marginal. +1 – Sascha Jan 31 '18 at 22:36
  • There is no "spread operator", there is spread syntax that uses the `...` [punctuator](http://www.ecma-international.org/ecma-262/8.0/index.html#sec-punctuators). ;-) – RobG Jan 31 '18 at 22:53
  • @RobG The more you know! – Zze Jan 31 '18 at 23:00
  • @Zze—pretty common error, see MDN URI vs page header: [*Spread syntax*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). – RobG Jan 31 '18 at 23:05
  • This is the concise answer I as looking for, but I'm using this in a pretty strictly-configured typescript app and I have to jump through so many extra little hoops to get this to work, I ended up using @Sascha' answer. – mellis481 Feb 01 '18 at 14:08
  • This does not return a UTC `Date` object, it returns a string. `date` is still a local date. – mellis481 Feb 01 '18 at 14:28