0

I need to make a function that takes a string and x number (subDays) of days as arguments and convert the string to a date and subtracts the x number of days from the date.

The input string is in format (YYYY-MM-DD) and I would like to get the same format back.

I get an Invalid Date error.

function newDate(date, subDays) {
    var myDate = new Date(date);
    myDate.setDate(myDate -subDays);
    console.log("Date: " + myDate);
}
Flemming Lemche
  • 169
  • 1
  • 3
  • 23

4 Answers4

3

Here is one way you can do it

console.log( toYMD( subDays( '2016-12-11', 3) ) );

function subDays(date, days) {
  var dateArray = date.split('-');
  var myDate = new Date(dateArray[0], dateArray[1] - 1, dateArray[2]);
  return new Date(myDate.setDate(myDate.getDate() - days));
}
function toYMD(d) {
  return d.getFullYear() + "-" +
         padZero(d.getMonth()+1) + "-" + 
         padZero(d.getDate());
}
function padZero(v) {
  return (v < 10) ? "0" + v : v;
}
Asons
  • 84,923
  • 12
  • 110
  • 165
2

It is recommended not to use parser of Date constructor as it can be implementation dependant, other than some widely accepted formats. So parse the string ourselves.

Make adjustments to date by getting milliseconds with getTime and adding/subtracting milliseconds.

function newDate(date, subDays) {
  function padZero(v) {
    return (v < 10) ? "0" + v : v;
  }
  var dateArray = date.split('-').map(Number);
  var myDate = new Date(dateArray[0], dateArray[1] - 1, dateArray[2]);
  myDate = new Date(myDate.getTime() - subDays * 24 * 60 * 60 * 1000)
  return myDate.getFullYear() + '-' + padZero(myDate.getMonth() + 1) + '-' + padZero(myDate.getDate());
}
console.log(newDate('2016-12-09', 8))
console.log(newDate('2016-12-09', 9))
sabithpocker
  • 15,274
  • 1
  • 42
  • 75
  • This is just spot on. Thank you very much. – Flemming Lemche Dec 11 '16 at 16:05
  • Use zero padding function as well for correct formatting. check the answer by @LGSon – sabithpocker Dec 11 '16 at 16:06
  • 1
    There is no need for `map(Number)`. Days should be added by [*adding days to the date*](http://stackoverflow.com/questions/9989382/add-1-to-current-date/9989458#9989458), not time since in places where daylight saving is observed, not all days are 24 hours long. Points for correctly parsing the string though. – RobG Dec 12 '16 at 03:17
  • @RobG Thank you for taking time to correct me. It is interesting to know about the day length difference in DST. I will take an in depth look into that. Regarding the `map(Number)` It is the second time I am getting this suggestion, I write this in my codes to make sure the array of strings from `split` is converted to an array of `numbers` as Date constructor expects `numbers`, is that an overkill? – sabithpocker Dec 12 '16 at 13:21
  • 1
    @sabithpocker—when the [*Date* constructor](http://ecma-international.org/ecma-262/7.0/index.html#sec-date-year-month-date-hours-minutes-seconds-ms) is passed more than one argument, it will call *ToNumber* on each of the parameters as the first step in processing them. Yes, it's overkill. ;-) – RobG Dec 13 '16 at 00:19
0

First you have to specify what you are trying to deduct ; try this :-

function newDate(date, subDays) {
var myDate = new Date(date);

myDate.setDate(myDate.getDate() -subDays);
console.log("Date: " + myDate);
}
A Biswas
  • 421
  • 6
  • 12
  • Thank you this solved my error with the missing .Getdate() – Flemming Lemche Dec 11 '16 at 16:06
  • Do not parse strings with the Date constructor. Dates in YYYY-MM-DD format will be treated as UTC, so for users west of Greenwich, the date will appear the be the day before. – RobG Dec 12 '16 at 03:18
0

There is a package called datejs and you can easily use addDays(), addHours(), addMinutes() on a Date object. Here is the API doc: https://code.google.com/archive/p/datejs/wikis/APIDocumentation.wiki

  function newDate(date, subDays) {
    const d = Date.parse(date).addDays(-parseInt(subDays));
    return `${d.getFullYear()}-${d.getMonth()}-${d.getDay()}`;
  }
Ping.Goblue
  • 576
  • 8
  • 12