2

In my JavaScript application I'm receiving a date in a string format, like this: 19/10/2021 (dd/mm/yyyy). I want to check if a month has passed since said date and return a true if so. I'm trying something like the following code, but it isn't working.

I'm getting some weird values when I try debugging it with console.logs and such, I'm a newbie in js so I don't know where I'm doing stuff wrong.

var q = new Date();
var d = q.getDate();
var m = q.getMonth() + 1; //+1 because january is 0 and etc
var y = q.getFullYear();

var today = new Date(d, m, y);

mydate = userDate; // this is the string the app is receiving

if (today - mydate > 30) {
    return true;
} else {
    return false;
}

Thanks in advance.

phentnil
  • 2,195
  • 2
  • 14
  • 22
  • Parse the string to a Date (see [*Javascript Issue converting string to date*](https://stackoverflow.com/questions/35401991/javascript-issue-converting-string-to-date)). Then add a month (see [*JavaScript function to add X months to a date*](https://stackoverflow.com/questions/2706125/javascript-function-to-add-x-months-to-a-date)), then see if the resulting date is less than `Date.now()`. If it is, then more than a month has passed. – RobG Nov 24 '21 at 01:12

4 Answers4

1

First, when you set q to new Date() it is today. There's no need to get from it the day, month, and year and then set it again. So for today you can just do var today = new Date().

Secound, you should pass into Date() y,m,d and not d,m,y.

Third, if you subtract a date from another, the calculation will be on milisecounds, not days.

This should work:

var userDate = '19/10/2021';
var myDate = new Date(userDate.split('/').reverse());
var today = new Date();

var thirtyDays = 1000*60*60*24*30;

return today - myDate > thirtyDays;
Mordy Stern
  • 797
  • 6
  • 12
  • `new Date(userDate.split('/').reverse())` will almost certainly return an invalid Date. – RobG Nov 24 '21 at 01:09
  • @RobG if userDate is a string in the format dd/mm/yyyy, then `userDate.split('/').reverse()` will return array like `[yyyy,mm,dd]`. and this is what the Date() constructor is getting as parameters. – Mordy Stern Nov 24 '21 at 19:17
  • You're passing a single value, an array. See [ECMA-262](https://262.ecma-international.org/#sec-date) and my comment on [this answer](https://stackoverflow.com/a/70087736/257182). – RobG Nov 24 '21 at 22:31
0

Try this:

    var q = new Date();
    var d = q.getDate();
    var m = q.getMonth(); 
    var y = q.getFullYear();
    var today = new Date(y,m,d);
    var mydate = new Date("2021-11-22"); 
    if(((today - mydate)/ (1000 * 60 * 60 * 24)) > 30)
    {
        return true;
    }
    else
    {
      return false;
    }
Mana S
  • 509
  • 2
  • 6
0

Because the definition of "age in months" is... flexible, the easiest way is to use a little arithmetic as you would compute it in your head, and not involve the Date class.

For the [a] human interpretation of "age in months", the rule is

  • Compute the difference between the two dates in months, as if the day-of-the-month was the 1st of the month for both dates

  • Subtract 1 to exclude the final month

  • Then, if the day-of-the-month of the last day of the period is on or after the day-of-the-month of the first day of the period, the [potentially partial] final month is complete: add 1 to restore the count

The one fly in the ointment is, since months contain different numbers of days, dealing with the cases where the 2 months differ in their number of days.

If, however, the end month is shorter than the start month, you can get into a situation where the boundary condition can never be met (e.g., the start date is the February 28th and the end date is March 31st. To fix that, you need to look at the "end of the month" as being a window ranging from the last day of the start month through the last day of the end month inclusive.

That leads to this code. I'm using a structure like the following to represent a date:

{
  year:  2021 , // 4-digit year
  month:   11 , // month of year (1-12 mapping to January-December)
  day:     23   // day of month (1-[28-31] depending on year/month
}

Ensuring that the data in that struct represents a valid date is left as an exercise for the reader.

The code is not that complicated:

/**
 * 
 * @param {object} bgn       - start date of period
 * @param {number} bgn.year  - 4-digit year
 * @param {number} bgn.month - month of year [1-12]
 * @param {number} bgn.day   - day of month [1-31]
 * 
 * @param {object} end       - end date of period
 * @param {number} end.year  - 4-digit year
 * @param {number} end.month - month of year [1-12]
 * @param {number} end.day   - day of month [1-31]
 * 
*/
function diffInMonths( bgn , end ) {
  const between = ( x , min , max ) => x >= min && x <= max;

  // We'll need to add back the final month based on the following:
  // - end.day >=  bgn.day -- we've passed the month boundary, or
  // - end.day is within the end-of-month window
  //   (when the end month is shorter than the start month)
  const needAdjustment = end.day >= bgn.day
    || between( end.day, daysInMonth(bgn), daysInMonth(end) );
  const finalMonthAdjustment = needsAdjustment ? 1 : 0;

  const deltaM = 12 * ( end.year - bgn.year )
    + ( end.month - bgn.month )
    - 1                    // remove the final month from the equation
    + finalMonthAdjustment // add in the precomputed final month adjustment
    ;

  return deltaM;
}

/**
 * 
 * @param {object} dt       - date
 * @param {number} dt.year  - 4-digit year
 * @param {number} dt.month - month of year [1-12]
 * @param {number} dt.day   - day of month [1-31]
 *
 */
function daysInMonth(dt) {
  const leapYear = ( dt.year % 4 === 0 && dt.year % 100 !== 0 ) || dt.year % 400 === 0;
  const monthDays = leapYear ? daysPerMonthLeap : daysPerMonth;
  const days = monthDays[dt.month];
  return days;
}
//                                    jan feb mar apr may jun jul aug sep oct nov dec
//                         ---------- --- --- --- --- --- --- --- --- --- --- --- ---
const daysPerMonth     = [ undefined, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ];
const daysPerMonthLeap = [ undefined, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, ];
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
-1

The problem is that you are subtracting a string from date. You need mydate to be the same type as today.

mydate = new Date(userDate)

(Note: This only works with 'month/day/year' format

Footanari
  • 1
  • 1
  • "*This only works with 'month/day/year' format*" is not correct, built–in parsers will parse (correctly or otherwise) a multitude of formats, often with differing results. General advice is "don't use the built–in parser", manually parsing d/m/y is not difficult. – RobG Nov 24 '21 at 01:14