2

Good day, I want to calculate the remaining days between the expiration date and the current date but it seems that the return is not what I expected.

function expiryDate(date_string) {

    var date = date_string.split("/");
    var year = parseInt(date[2]);
    var day = parseInt(date[1]);
    var month = parseInt(date[0]);

var expiration = new Date(month,day,year);

   var d = new Date();
var curr_day = d.getDate();
var curr_month = d.getMonth()+1;
var curr_year = d.getFullYear();

var current_date = new Date(curr_month, curr_day, curr_year);

return (expiration - current_date) / (1000*60*60*24);
}

the code above will return the correct remaining days if the dates are the same for example.. the current date string was 05/01/2018 and the expiration is also the same and it will return 0, but when i move the expiration date to 1 day like 05/02/2018 the return is 28 days which is not correct.

How can I fix this problem?

Vikasdeep Singh
  • 20,983
  • 15
  • 78
  • 104
basaya
  • 126
  • 1
  • 4
  • 13
  • 1
    I'd recommend using a library like moment (see:https://momentjs.com/docs/#/displaying/difference/) and avoid concerning yourself with timezones/leap seconds/etc/etc. – AJ X. May 01 '18 at 03:42
  • Months are zero indexed, so `var month = date[0] - 1`. There is no need for *parseInt* or for a library. The difference in days is just `Math.round((expiration - current_date)/8.64e7)` and you're done. – RobG May 01 '18 at 07:13

4 Answers4

3

As others have pointed out, months are zero indexed. Also, your method of zeroing the hours won't always work as expected because of daylight saving in some places. But rounding the result will remove DST effects.

There is no need for a library, your parse function and calculation can be be hugely simplified, you could easily remove another line from the following:

/* @param {string} date_string - date in m/d/y format
** @returns {number} days between today and expiry
*/
function expiryDays(date_string) {
  var b = date_string.split(/\D/);
  var expiry = new Date(b[2],--b[0],b[1]);
  return Math.round((expiry - new Date().setHours(0,0,0,0)) / 8.64e7);
}

console.log(expiryDays('8/23/2018'));

// Or if you like obfuscated code
var expires = s=>Math.round((new Date(...(s.split(/\D/).reduce((a,v,i) => {a[(i+1)%3] = (i==0? v-1 : v);return a},[]))) - new Date().setHours(0,0,0,0))/8.64e7);

console.log(expires('8/23/2018'));
RobG
  • 142,382
  • 31
  • 172
  • 209
  • This is what I'm looking for, no library is the best answer for. thank you sir. you are bit too late to mark your answer as a correct but your answer help me a lot.. – basaya May 01 '18 at 09:26
  • @basaya—forgot to mention that the *expiryDays* function is compatible with every implementation in use. – RobG May 01 '18 at 13:24
1

The Date object uses a zero-based month where January is 0, February is 1, etc. You seem to have tried in one place to compensate for that, but in the wrong way.

You need to fix this line like this:

var month = parseInt(date[0]) - 1;

And this line like this:

var curr_month = d.getMonth(); // No +1

Of course, using Moment.js, as suggested, is also a good idea, but I thought you might want to know how to get your own code working.

kshetline
  • 12,547
  • 4
  • 37
  • 73
  • I changed the code and I tried your suggestion but its like just the same result as my problem.. if my expiration date is 05/02/2018 the return days remaining is 29 instead of 1 day... I want to know how it works just like you've said but i think the moment library is the best way... – basaya May 01 '18 at 04:56
0

You can difference between two dates using momentjs's diff() function

Below is working code:

function expiryDate(date_string) {
  var expiration = moment(date_string).format("YYYY-MM-DD");
  var current_date = moment().format("YYYY-MM-DD");
  var days = moment(expiration).diff(current_date, 'days');
  return days;
}

alert("Days remaining = " + expiryDate("2018-05-05"));
console.log("Days remaining = " + expiryDate("2018-05-05"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.js"></script>
Vikasdeep Singh
  • 20,983
  • 15
  • 78
  • 104
  • I've got Warning says Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release.. is that okey? – basaya May 01 '18 at 04:47
  • @basaya yes this is what I mentioned in comment next to alert function. `"MM/DD/YYYY"` is not recommended date format. You should use some other formats or simply ignore it. – Vikasdeep Singh May 01 '18 at 04:48
  • @basaya here are supported format. Use any of them : http://momentjs.com/docs/#/parsing/string/ – Vikasdeep Singh May 01 '18 at 04:53
  • @basaya for example: just change format to "YYYY-MM-DD" and you will see no warning – Vikasdeep Singh May 01 '18 at 04:55
  • @basaya for your convenience I have updated the date format. No warnings now. – Vikasdeep Singh May 01 '18 at 04:59
  • 1
    I think your answer is the best answer for me. my project was already in this date format "MM/DD/YYYY" but string.replace() can fix that.. I will mark your answer as correct.. thanks for your help. :-) – basaya May 01 '18 at 05:18
  • An answer should not rely on a library that is neither tagged nor mentioned in the OP. You might suggest one as part of the answer thought. And parsing a string to a moment object, then formatting it as a string only to parse it again to a moment object is inefficient to say the least. – RobG May 01 '18 at 07:15
-1

initially working with times is a lot of work sometimes, and often you will invest a lot of time, maybe the moment.js library may be a solution for you depending on the need, specifically the isBetween

follow the link below.

moment.js

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days')