0

I need to subtract a date like 1/26/2015 from a date-time like 2016-01-27T01:10:57.569000+00:00. From what I've read converting both to distance in milliseconds from Epoch and then subtracting is the easiest way. I've tried using various methods, but all the methods seem to say 2016-01-27T01:10:57.569000+00:00 is invalid data. The method .getTime() works great for the 1/26/2015 format, but it can't read the 2016-01-27T01:10:57.569000+00:00.

How does one go about getting the date/time UTC time into milliseconds?

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Thunder Cat King
  • 612
  • 9
  • 17
  • Can you post the code you've tried? We can help troubleshoot if we know what you've done. – Adam Konieska Feb 01 '16 at 20:42
  • I don't use google apps script, but generally you should never allow the Date constructor to parse strings, it is unreliable (see [*this answer*](http://stackoverflow.com/questions/2488313/javascripts-getdate-returns-wrong-date/2488358#2488358), and many like it). It's simple to create a function to split the string into its components and pass them to the constructor (remember to subtract 1 from the month). – RobG Feb 01 '16 at 20:49

3 Answers3

1

On a complicated way you can use a regex to extract each part of the date as string and then use them in a new Date with all parameters:

function getTimeDifference(){
  var regEx = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):([\d.]+)/;
  var dateString = '2016-01-27T01:10:57.569000+00:00';
  var r = regEx.exec( dateString );
  var date1 = new Date(r[1], r[2]-1, r[3], r[4], r[5], r[6]); // Notice the -1 in the month
  var date2 = new Date('1/26/2015');
  var difference = date1 - date2;
  Logger.log(difference);
}
Kriggs
  • 3,731
  • 1
  • 15
  • 23
  • 2
    Note that you are turning a UTC date string into local, you should use `new Date(Date.UTC(...))`. Otherwise, you were doing OK up to `new Date('1/26/2015')`. Don't ever pass strings to the Date constructor, it is very unreliable. Better to manually parse that too (2 lines instead of 1). – RobG Feb 02 '16 at 02:23
1

I ended up using this. When I call parseDate(), I used getTime() to get the date in milliseconds then subtracted them and converted them to days. For my use case the time didn't have to be down to the second, but if it did, it wouldn't be hard to parse more info from the string. I ran into trouble initially because as a beginner Javascript writer I didn't know why apps script wouldn't accept this format into the date constructor.

function parseDate(str) {
//This should accept 'YYYY-MM-DD' OR '2016-01-27T01:10:57.569000+00:00'
if(str.length == 10){
    var mdy = str.split('-');
    return new Date(mdy[0], mdy[1]-1, mdy[2]);
    }
else
   {
   var mdy = str.split('-');
   var time = mdy[2].split('T');
   var hms = time[1].split(':');
   return new Date(mdy[0], mdy[1]-1, time[0], hms[0], hms [1]);
   
   }
}
Thunder Cat King
  • 612
  • 9
  • 17
1

If you are confident that the values in the date strings will always be valid and that the ISO8601 string will always have offset 00:00 (i.e. UTC), then simple parse functions are:

// Parse ISO 8601 format 2016-01-27T01:10:57.569000+00:00
function parseISOUTC(s) {
  var b = s.split(/\D/);
  return new Date(Date.UTC(b[0],b[1]-1,b[2],b[3],b[4],b[5],b[6]));
}

document.write(parseISOUTC('2016-02-04T00:00:00.000+00:00'));

// Parse US format m/d/y
function parseMDY(s) {
  var b = s.split(/\D/);
  return new Date(b[2],b[0]-1,b[1]);
}
    
document.write('<br>'+ parseMDY('2/4/2016'))    
    
document.write('<br>'+ (parseISOUTC('2016-02-04T00:00:00.000+00:00') - parseMDY('2/4/2016')))

Note that the first string is UTC and the second will be treated as local (per ECMAScript 2015), so the difference between 2016-02-04T00:00:00.000+00:00 and 2/4/2016 will be the time zone offset of the host system.

RobG
  • 142,382
  • 31
  • 172
  • 209