How to get the exact quantity of months between two dates? - javascript

I'm trying to get the quantity of months between two dates
but for some reason, the moment diff method some times returns the correct number and some times is wrong (by one month), (depending on the dates I guess)
var estDate = "some date"; //2022-06-02
estDate = estDate.toString();
var estDateYear = estDate.substring(0,4);
var estDateMonth = estDate.substring(4, 6);
var estDateDay = estDate.substring(6, 8);
estDate = estDateYear + '-' + estDateMonth + '-' + estDateDay;
//first date
estDate = moment(estDate);
//actual date
var date = moment();
//DIFF
var diff= date.diff(estDate, 'month');
diff= diff.toString();
Any Idea why this happens?

You should set the third argument in the diff method to true. This will return fractions of a month instead of a whole number. Then, you can round as needed to return the number you would like.
var diff = Math.floor(date.diff(estDate, 'month', true));
Documentation
https://momentjs.com/docs/#/displaying/difference/
By default, moment#diff will truncate the result to zero decimal places, returning an integer. If you want a floating point number, pass true as the third argument.

Why not just parse the estDate string using moment to begin with?
var estDate = "2022-06-02"; //2022-06-02
estDate = moment(estDate, "YYYY-MM-DD");
//actual date
var date = moment();
//DIFF
var diff= date.diff(estDate, 'month');
diff= diff.toString();

// Simply use Momentjs Formation library
//let estDate = "2022-06-02";
let estDate = moment("2022-06-02", "YYYY-MM-DD");
let actualdate = moment();
let diff= actualdate.diff(estDate, 'M');
diff= diff.toString();
console.log(diff);
<div>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.min.js"></script>
</div>

Related

Moment.js Duration between Two Dates

How do I get the time difference between two different dates variables, specifically in years, months and days using moment.js?
I found this method but I keep getting weird results. Sometimes the result is one month ahead so I added a subtract one months part to make the result correct, but when the difference between the two dates can be divided into whole years it then becomes a month behind, but then if I remove the subtract month part, it gets even more out of whack.
Also I would like to format it as "X Years, Y Months, Z days", but also can't figure out how to format it in such way.
var dateOne = new Date(2000,07,16);
var dateTwo = new Date (1990,07,16);
var updatedDate = moment(dateOne).format('ll');
var x = moment(dateOne, 'DD/MM/YYYY').diff(moment(dateTwo, 'DD/MM/YYYY'))
var y = moment.duration(x);
var why = moment(x).subtract(1, 'M');
var z = Math.floor(y.asYears()) + moment.utc(why).format('/MM/DD');
console.log(z);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Try this perhaps?
var firstDate = moment();
var secondDate = moment("2018-03-19");
var yearDiff = firstDate.diff(secondDate, "year");
var monthDiff = firstDate.diff(secondDate, "month");
var dayDiff = firstDate.diff(secondDate, "day");
console.log(yearDiff + " Years, " + monthDiff + " Months, " + dayDiff + " Days");
https://jsfiddle.net/px1brLdk/
As stated by others in the comments, you can't format a duration as a date and since dateOne and dateTwo are a Date objects, there is no need for the second argument in moment(dateOne, 'DD/MM/YYYY'), simply use moment(Date).
Moverover, please note that when you use new Date(year, monthIndex, day) monthIndex starts from 0, see MDN docs:
The argument monthIndex is 0-based. This means that January = 0 and December = 11.
You can use moment-duration-format plug-in to format momentjs duration according your needs, see format() docs on the plug-in page.
Here a live sample:
var dateOne = new Date(2000, 7, 16);
var dateTwo = new Date(1990, 7, 16);
var diff = moment(dateOne).diff(moment(dateTwo))
var dur = moment.duration(diff);
var result = dur.format();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/2.2.2/moment-duration-format.min.js"></script>
Moment is having a method called .diff() Use that one.
https://momentjs.com/docs/#/displaying/difference/

Array of days in between months

I have two dates: Startdate and enddate
startdate = "10/10/2018" enddate = "03/09/2019"
I am trying to create an array of dates between those 2 dates. I have the following code.
function getDateArray (start, end) {
var arr = [];
var startDate = new Date(start);
var endDate = new Date(end);
endDate.setMonth( endDate.getMonth());
while (startDate <= endDate) {
arr.push(new Date(startDate));
startDate.setMonth(startDate.getMonth() + 1);
}
return arr;
}
Then calculate the number of days between those months in between.
10/10/2018 to 11/10/2018 = 30 days
11/10/2019 to 12/10/2018 = 30 days or so depending on number of days between the 2 dates and then create an array of the dates.
[30,30,31....till end date]
function daysBetween(date1, date2 )
{
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var dayDifference = Math.ceil(timeDiff / (1000 * 3600 * 24));
return dayDifference;
}
I tried the following code and it's returning the array of number of dates however, it's not accurate. It keeps returning 32 days in October. The output it's giving right now is as follows. I am not sure what i am doing wrong here but it looks like it's only going till February and displaying the result.
Any help will be appreciated. Thank you.
Output: [32,30,31,31,28]
var dateArr = getDateArray(z, y);
console.log(dateArr);
var dayCounts = "";
for (var x = 0; x < dateArr.length-1; x++)
{
dayCounts += daysBetween(dateArr[x], dateArr[x+1]);
}
console.log("datearrlength" + dateArr.length);
console.log(dayCounts);
i think this will work for you,
Date.prototype.addDay= function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
function getDateBwStartandEnd(sdate, edate) {
var dateArray = new Array();
var currentDate = sdate;
while (currentDate <= edate) {
dateArray.push(new Date (currentDate));
currentDate = currentDate.addDay(1);
}
return dateArray;
}
** Shamelessly copied from web, but this works fine for me.
While the following doesn't answer your question it is an alternative approach to the overall problem you are attempting to solve.
One approach would be to simply get the time difference between the two dates and then divide by the number of microseconds in a day. As you will notice though it is not exact and so a floor is used to get the days. There are other concerns with this approach as well such as date ranges before the epoch but it is a very simplistic approach and might work depending on your needs.
const startDate = '10/10/2018';
const endDate = '03/09/2019';
const start = (new Date(startDate)).valueOf();
const end = (new Date(endDate)).valueOf();
const timeBetween = end - start;
console.log({timeBetween, days: Math.floor(timeBetween/86400000)});
A slightly more robust is to essentially use a counter that increments itself by adding 1 day to the counter and the start date while the start date is less than the end date. Again, there are some concerns with this approach but that also depends on your needs.
const startDate = '10/10/2018';
const endDate = '03/09/2019';
let start = new Date(startDate);
const end = (new Date(endDate)).valueOf();
let daysBetween = 0;
while (start.valueOf() < end) {
daysBetween++;
start.setDate(start.getDate() + 1);
}
console.log(daysBetween);
Finally, a more robust solution to avoid the variety of issues with manipulating and working with dates is to use a library like momentjs. Using its difference method would look like the following.
const start = moment([2018, 10, 10]);
const end = moment([2019, 3, 9]);
console.log(end.diff(start, 'days'));
<script src="http://momentjs.com/downloads/moment.min.js"></script>
Using the following code worked for me. I added 1 extra month to my end date and it gives the proper date range. Also, instead of Math.ceil, i used Math.round and it gives the right number of date.
function getDateArray (start, end) {
var arr = [];
var startDate = new Date(start);
var endDate = new Date(end);
endDate.setMonth( endDate.getMonth());
while (startDate <= endDate) {
arr.push(new Date(startDate));
startDate.setMonth(startDate.getMonth() + 1);
}
return arr;
}

Add a variable number to a date in Java script

I have read a few articles but nothing seems to the point. I have created a form that records a reservation date (when a user wants to reserve a game) and the number of days they hope to borrow it for. I want to add this to the reservation date to get the date the game must be returned by. I have wrapped up my code so far into a function so that I can call it using an onclick method. What should this code look like to work properly? Almost forgot - to make life hard my date is written like this YYYY-MM-DD
function ReturnDate(){
var reservation_begin = document.getElementById('reservation_start').value;
var loan_period = document.getElementById('requested_days').value;
var reservation_end = document.getElementById('return_date');
var dateResult = reservation_begin + loan_period;
return_date.value = dateResult;
}
USING the Suggestions made by Linus
I made the following alterations but had trouble with the formatting of the return date. e.g Setting the reservation date to 2015-01-03 gave me the result of 2015-0-32 for the return date
function ReturnDate(){
var reservation_begin = document.getElementById('reservation_start').value;
var loan_period = document.getElementById('requested_days').value;
var resDate = new Date(reservation_begin);
alert(resDate)
var period = loan_period;
var output = document.getElementById('return_date');
resDate.setDate(resDate.getDate() + period);
alert(period)
//return_date.value = resDate.getFullYear() + "-" + (resDate.getMonth() + 1) + "-" + resDate.getDate();
return_date.value = resDate.getFullYear() + "-" + resDate.getMonth() + "-" + (resDate.getDate() +1);
}
As mentioned dates could be a bit tricky to handle with js.
But to just add days to a date this could be a solution?
JSBIN: http://jsbin.com/lebonababi/1/edit?js,output
JS:
var resDate = new Date('2015-02-01');
var period = 6;
var output = "";
resDate.setDate(resDate.getDate() + period);
output = resDate.getFullYear() + "-" + (resDate.getMonth() + 1) + "-" + resDate.getDate();
alert(output);
EDIT:
Added a new JSBin which is more consistent with the original code.
JSBin: http://jsbin.com/guguzoxuyi/1/edit?js,output
HTML:
<input id="reservationStart" type="text" value="2015-03-01" />
<br />
<input id="requestedDays" type="text" value="14" />
<br />
<a id="calculateDate" href="javascript:;">Calculate Date</a>
<br /><br /><br />
Output:
<input id="calculatedDate" type="text" />
JS:
// Click event
document.getElementById('calculateDate').addEventListener('click', returnDate);
// Click function
function returnDate(){
var reservationStart = document.getElementById('reservationStart').value,
requestedDays = parseInt(document.getElementById('requestedDays').value),
targetDate = new Date(reservationStart),
formattedDate = "";
// Calculate date
targetDate.setDate(targetDate.getDate() + requestedDays);
// Format date
formattedDate = formatDate(targetDate);
// Output date
document.getElementById('calculatedDate').value = formattedDate;
}
// Format date (XXXX-XX-XX)
function formatDate(fullDate) {
var dateYear = fullDate.getFullYear(),
dateMonth = fullDate.getMonth()+1,
dateDays = fullDate.getDate();
// Pad month and days
dateMonth = pad(dateMonth);
dateDays = pad(dateDays);
return dateYear + "-" + dateMonth + "-" + dateDays;
}
// Pad number
function pad(num) {
return (num < 10 ? '0' : '') + num;
}
As per my comment,
Split reservation_begin and use the Date constructor feeding in the
parts to create a Javascript date object. getTime will give you the
milliseconds since the Epoch. There are 86400000 milliseconds in a day, so
multiply this by loan_period. Add the two millisecond result together
and use the Date constructor with your total milliseconds to get
dateResult as a Javascript date object.
using Date.UTC but you don't have to.
function pad(num) {
return num < 10 ? '0' + num : num;
}
var reservation_begin = ('2015-02-01').split('-'),
loan_period = '5',
begin,
end;
reservation_begin[1] -= 1;
begin = new Date(Date.UTC.apply(null, reservation_begin)).getTime();
end = new Date(begin + 86400000 * loan_period);
document.body.textContent = [
end.getUTCFullYear(),
pad(end.getUTCMonth() + 1),
pad(end.getUTCDate())
].join('-');
Why split the date string into parts? This is to avoid cross browser parsing issues.
Why use milliseconds? This is the smallest value represented by Javascript Date, using this will avoid any rollover issues that may be present in browsers.
Why use UTC? You haven't specified the requirements for your script, and this is about as complex as it gets. You don't have to use it, you can just feed the parts into Date and use the non UTC get methods.
What does pad do? It formats the month values to MM and date values to DD.
Note that month is zero referenced in Javascript so months are represent by the numbers 0-11.
A bit confused with the third variable "reservation_end" but according to your question this solution might work.
var dateResult = new Date(reservation_begin);
dateResult.setDate(dateResult.getDate() + parseInt(loan_period));
alert(dateResult);
http://jsfiddle.net/uwfpbzt2/
Example using todays date:
var today = new Date();
today.setDate(today.getDate() + x);
where x is the number of days. Then just use getYear(), getMonth() and getDate() and format it how you like.
EDIT
var myDate = new Date(year, month, day, hours, minutes, seconds, milliseconds);
Assuming your date is entered in dd/mm/yyyy format as inputDate then
dateParts = inputDate.split("/");
var myDate = new Date(dateParts[2], dateParts[1]-1, dateParts[0]);
Depending on the date format your split() delimiter and array positions may be different but this is the general idea.

Time from X not working as expected moment.js

$.each(data[i].replies, function(m, n) {
var currentdate = new Date();
console.log(n.entry.date_entered);
check = moment(n.entry.date_entered, 'YYYY/MM/DD');
check1 = moment(currentdate, 'YYYY/MM/DD');
console.log(check);
console.log(check1);
var month = check.format('M');
var day = check.format('DD');
var year = check.format('YYYY');
var month1 = check1.format('M');
var day1 = check1.format('DD');
var year1 = check1.format('YYYY');
get = moment([year, month, day]);
get1 = moment([year1, month1, day1]);
g = get1.from(get);
});
Sample n.entry.date_entered : 2014-07-28 12:23:43
For all the dates i am getting a few seconds ago don't know why
I think your problem is the format mask that you pass in to moment.
In your sample you use - as the delimiter but in your format mask you use /. This way moment will not be able to parse the date and will give you the current date instead.
Try changing your format mask to "YYYY-MM-DD".

calculate difference between two timestamp and get difference in unix timestamp

I want to calculate the difference between two dateTime, one date is submitted by user and other is current time:
user submitted time - now = difference in unix
user submitted time format is:
2014-03-26 10:52:00
Thanks for your help.
You can simply do this with getTime() which returns the number of milliseconds.
var ds = "2014-03-26 10:52:00";
var newDate = new Date(ds).getTime(); //convert string date to Date object
var currentDate = new Date().getTime();
var diff = currentDate-newDate;
console.log(diff);
Sometimes there are chance for cross browser compatibility in parsing the date string so it is better to parse it like
var ds = "2014-03-26 10:52:00";
var dateArray = ds.split(" "); // split the date and time
var ds1 = dateArray[0].split("-"); // split each parts in date
var ds2 = dateArray[1].split(":"); // split each parts in time
var newDate = new Date(ds1[0], (+ds1[1] - 1), ds1[2], ds2[0], ds2[1], ds2[2]).getTime(); //parse it
var currentDate = new Date().getTime();
var diff = currentDate - newDate;
console.log(diff); //timestamp difference
You can use MomentJS library
var user_submited_time = moment('2014-03-26 10:52:00');
var now = moment();
var value = user_submited_time - now;

Categories