Date Calculation Error - javascript

I have below calculation:
vCurrDate = new Date();
vDueFromDate = new Date();
vDueToDate = new Date();
vOverDueToDate = new Date();
vCurrDate.setDate(vCurrDate.getDate() - 1);
vDueFromDate.setDate(vCurrDate.getDate() - 30);
vDueToDate.setDate(vCurrDate.getDate());
vOverDueToDate.setDate(vCurrDate.getDate() - 31);
On March 02 2018 (today), all the above calculations are working fine.
But, on March 01 2018, last three calculations went wrong.
Below shows the result of above calculations with both mentioned dates:
--On March 02 2018 (today)
Thu Mar 01 2018 12:03:34 GMT+0530 (India Standard Time) **** 01-Mar-2018
Tue Jan 30 2018 12:03:34 GMT+0530 (India Standard Time) **** 30-Jan-2018
Thu Mar 01 2018 12:03:34 GMT+0530 (India Standard Time) **** 01-Mar-2018
Mon Jan 29 2018 12:03:34 GMT+0530 (India Standard Time) **** 29-Jan-2018
--On March 01 2018 (yesterday)
Wed Feb 28 2018 12:12:32 GMT+0530 (India Standard Time) **** 28-Feb-2018
Mon Feb 26 2018 12:12:32 GMT+0530 (India Standard Time) **** instead of 29-jan-2018
Wed Mar 28 2018 12:12:32 GMT+0530 (India Standard Time) **** 28-Feb-2018
Sun Feb 25 2018 12:12:32 GMT+0530 (India Standard Time) **** 28-jan-2018

Hmmm....Look. From documentation we now about .setDate(..) next:
If the dayValue is outside of the range of date values for the month, setDate() will update the Date object accordingly. For example, if 0 is provided for dayValue, the date will be set to the last day of the previous month.
Let's understand what happens with your date on March 1st.
vCurrDate.setDate(vCurrDate.getDate() - 1);
After that vCurrDate assigned to 28th of February according to setDate specification
vDueFromDate.setDate(vCurrDate.getDate() - 30);
To vDueFromDate you set date as 28-30 or -2 days from current date. 0 means last day of previous months, so -2 is a 26th of February
vDueToDate.setDate(vCurrDate.getDate());
As mentioned above vCurrDate.getDate() now is 28, so we set vDueToDate to 28th of current month, i.e. 28th of March.
vOverDueToDate.setDate(vCurrDate.getDate() - 31);
In this case you tried to set date to -3 of current month, so, as it mentioned above, this is 25th of Feb

Related

Sorting dates including undefined and null

Im trying to sort data in order of ending soonest. this is my code and you can see the console results below. The sort is working somewhat but not completely. Can anyone help?
I see its to do with the invalid date but I can't work out how to get around this. The Invalid date field is blank in the JSON data that's pulled in. Null/undefined I would like to be last.
if (this.sortBy === "ending") {
filteredResults.sort((a, b) => {
var aDate = new Date(a.metaData.t);
var bDate = new Date(b.metaData.t);
console.log(b.metaData.t);
if (!aDate) {
aDate = 99999999; }
console.log("adate" + aDate);
if (!bDate) {
bDate = 99999999;
}
console.log("bdate" + bDate);
if (aDate > bDate) {
return 1;
}
if (aDate < bDate) {
return -1;
}
return 0;
});
}
return filteredResults;
},
Console.log data results
adateWed Nov 30 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
bdateTue Dec 13 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
adateWed Nov 30 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
bdateFri Sep 09 2022 00:00:00 GMT+0100 (British Summer Time)
adateWed Nov 30 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
bdateWed Nov 30 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
adateWed Nov 30 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
bdateThu Dec 08 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
adateWed Nov 30 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
bdateMon Dec 05 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
adateInvalid Date
bdateTue Dec 13 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
adateInvalid Date
bdateFri Mar 31 2023 00:00:00 GMT+0100 (British Summer Time)
adateInvalid Date
bdateSun Aug 20 2023 00:00:00 GMT+0100 (British Summer Time)
adateInvalid Date
bdateTue Jan 01 2030 00:00:00 GMT+0000 (Greenwich Mean Time)
adateInvalid Date
bdateTue Dec 13 2022 00:00:00 GMT+0000 (Greenwich Mean Time)
Invalid Date
Filtered results - the JSON is not exact here as its too big to add to this question. The format of the data is correct locally
(1 example I have XX most of the data for privacy reasons)
filteredResults {
K:"XX"
D:"XX"
N:"XX"
y:"XX"
t:"3 August 2022"
u:"XX"
X:"XX"
R:"XX"
T:"XX"
E:"XX"
}
.....
80 more rows like this but with various dates
You could check the value in advance and move unknown dates to the end of the array.
// assuming iso 8601 dates (same time zone or zulu), null or undefined
data.sort((a, b) =>
!a.date - !b.date ||
a.date.localeCompare(b.date)
);

Code appears to be assigning when it should just be reading values

So I have this code:
var shotTime = this.lastShot;
shotTime.setMilliseconds(this.lastShot.getMilliseconds() + this.shootGrace);
console.log(shotTime);
console.log(new Date);
console.log(new Date()>shotTime);
console.log("-------------------------------");
if(new Date()>shotTime){
console.log("##############################");
this.lastShot = new Date();
}
This produces this output:
Mon Mar 12 2018 20:35:44 GMT+0000 (GMT Standard Time)
Mon Mar 12 2018 20:35:45 GMT+0000 (GMT Standard Time)
true
-------------------------------
##############################
Mon Mar 12 2018 20:35:45 GMT+0000 (GMT Standard Time)
Mon Mar 12 2018 20:35:45 GMT+0000 (GMT Standard Time)
false
-------------------------------
Mon Mar 12 2018 20:35:46 GMT+0000 (GMT Standard Time)
Mon Mar 12 2018 20:35:45 GMT+0000 (GMT Standard Time)
false
-------------------------------
Mon Mar 12 2018 20:35:46 GMT+0000 (GMT Standard Time)
Mon Mar 12 2018 20:35:46 GMT+0000 (GMT Standard Time)
false
-------------------------------
Mon Mar 12 2018 20:35:47 GMT+0000 (GMT Standard Time)
Mon Mar 12 2018 20:35:50 GMT+0000 (GMT Standard Time)
true
-------------------------------
##############################
This is rather odd as this.lastShot appears to be changing while false while it should only change when true. I can't figure out why there is this change.
Thanks,Ed.
shotTime = this.lastShot;
When you do this, you're not making a copy. You now have two references to the same Date object. Changing one of the references will now affect both. When you change shotTime, you're changing this.lastShot as well. Do this as a test:
var shotTime1 = new Date();
console.log(shotTime1.getMilliseconds());
var shotTime2 = shotTime1;
shotTime2.setMilliseconds(0);
console.log(shotTime1.getMilliseconds());
And you'll see the second one is zero because shotTime1 and shotTime2 both reference the same Date object.

please explain my error in this javascript date math

Here's the output from the Visual Studio Immediate Window. I start with mondaysDate, create a second date, thisDate, and then add integers to it using mondaysDate as the base.
I don't understand why adding 3 to the date yields November 2 and adding 4 to the date yields December 4th.
Is it illegal to invoke setDate() more than once?
?mondaysDate
Mon Oct 30 2017 00:00:00 GMT-0400 (Eastern Daylight Time)
?thisDate
Mon Oct 30 2017 00:00:00 GMT-0400 (Eastern Daylight Time)
?thisDate.setDate(mondaysDate.getDate() + 3)
1509595200000
?thisDate
Thu Nov 02 2017 00:00:00 GMT-0400 (Eastern Daylight Time)
?thisDate.setDate(mondaysDate.getDate() + 4)
1512363600000
?thisDate
Mon Dec 04 2017 00:00:00 GMT-0500 (Eastern Standard Time)
?mondaysDate
Mon Oct 30 2017 00:00:00 GMT-0400 (Eastern Daylight Time)
The issue is that first time you add 33 days from Oct 1, then you add 34 days from Nov 1.
thisDate.setDate(mondaysDate.getDate() + 3)
// You set the date to 30 + 3 (33) days from the first day of the current month (Oct 1)
// Oct 1 + 33 days = Nov 2
// thisDate = Thu Nov 02 2017 00:00:00 GMT-0400 (Eastern Daylight Time)
thisDate.setDate(mondaysDate.getDate() + 4)
// You set the date to 30 + 4 (34) days from the first day of the current month (Nov 1)
// Nov 1 + 34 days = Dec 4
// thisDate = Mon Dec 04 2017 00:00:00 GMT-0500 (Eastern Standard Time)
The date is set relative to thisDate, starting at 1st of the current month, and adds the day number in mondaysDate + 4 days. Every time you call setDate, you update thisDate.
You can read more about setDate on MDN.

How could I get the number of dates that fit a given month in a javascript array of momentjs dates?

I have a specific array of momentjs dates like this:
Schema:
tasks.data: [
{startDate: Mon Nov 25 2013 20:32:28 GMT-0500 (Eastern Standard Time)},
{startDate: Tue Nov 26 2013 20:32:28 GMT-0500 (Eastern Standard Time)},
{startDate: Wed Nov 27 2013 20:32:28 GMT-0500 (Eastern Standard Time)},
{startDate: Thu Nov 28 2013 20:32:28 GMT-0500 (Eastern Standard Time)},
{startDate: Fri Nov 29 2013 20:32:28 GMT-0500 (Eastern Standard Time)}
]
rest of the data..
Mon Nov 25 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Tue Nov 26 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Wed Nov 27 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Thu Nov 28 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Fri Nov 29 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Sat Nov 30 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Sun Dec 01 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Mon Dec 02 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Tue Dec 03 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Wed Dec 04 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Thu Dec 05 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Fri Dec 06 2013 20:32:28 GMT-0500 (Eastern Standard Time)
Give say the Month of November 2013, how can I determine the count of dates that fall within that month and year? As my array has dates that span over 3 years.
My ultimate goal us to use the count in creating a sort of like gantt chart and use colspan="" on the month header based on the number of dates.
The information I have is the array of dates and the month and year I want to check.
Something like
return GetDateCounts(Month, Year){
return dateArry.map.indexOf(moment(startDate).month() == Month && moment(startDate).year() == Year)
}
Edit: with no duplicates.
Example:
If I have dates from Nov 21st-30th 2013, that should be count of 9, or 9 days.
If I have two repeating dates for the 21st, I would want to ignore that and only still have a count of 9.
Ok I managed out this convoluted function that works, but I'm sure there's got to be a better/fast, less lines of codes way to do this. Note I had to flatten my complex object cause I couldn't figure out how to loop through data.startDate, so I created a flat array of the dates in vm.dates.
If someone can come up with a better way I'll give the answer to them.
var uniqueDates = [];
var count = 0;
var unique = false;
vm.dates.forEach(function (date) {
if (moment(date).month() == month && moment(date).year() == year) {
unique = true;
//Attempt to find previous "day" in unique array list
uniqueDates.forEach(function (uniqueDate) {
if (moment(uniqueDate).date() == moment(date).date()) {
//If found set Unique to False
unique = false;
}
});
if (unique == true) {
//If Unique count
count++;
//and add found date to the Unique List
uniqueDates.push(date);
unique = false;
}
};
});
return count;

Using Moment.js to make an array of this week's dates doesn't add to array

I'm using Moment.js to make a Resource Calendar and I need an array of dates for this week. The console log of my current function prints out appropriately but the array that gets pushed in for each date is wrong.
var startOfWeek = moment().startOf('week');
var endOfWeek = moment().endOf('week');
var days = [];
var day = startOfWeek;
do {
console.log(day._d);
days.push(day._d);
day = day.add(1, 'd');
}
while (day <= endOfWeek);
console.log(days);
Returns:
Sun Jan 18 2015 00:00:00 GMT-0500 (EST) schedule.js?320233fd69f9859ccb55248b608e15891032b17d:31
Mon Jan 19 2015 00:00:00 GMT-0500 (EST) schedule.js?320233fd69f9859ccb55248b608e15891032b17d:31
Tue Jan 20 2015 00:00:00 GMT-0500 (EST) schedule.js?320233fd69f9859ccb55248b608e15891032b17d:31
Wed Jan 21 2015 00:00:00 GMT-0500 (EST) schedule.js?320233fd69f9859ccb55248b608e15891032b17d:31
Thu Jan 22 2015 00:00:00 GMT-0500 (EST) schedule.js?320233fd69f9859ccb55248b608e15891032b17d:31
Fri Jan 23 2015 00:00:00 GMT-0500 (EST) schedule.js?320233fd69f9859ccb55248b608e15891032b17d:31
Sat Jan 24 2015 00:00:00 GMT-0500 (EST) schedule.js?320233fd69f9859ccb55248b608e15891032b17d:31
[Sun Jan 25 2015 00:00:00 GMT-0500 (EST), Sun Jan 25 2015 00:00:00 GMT-0500 (EST), Sun Jan 25 2015 00:00:00 GMT-0500 (EST), Sun Jan 25 2015 00:00:00 GMT-0500 (EST), Sun Jan 25 2015 00:00:00 GMT-0500 (EST), Sun Jan 25 2015 00:00:00 GMT-0500 (EST), Sun Jan 25 2015 00:00:00 GMT-0500 (EST)]
Notice how the array at the bottom is the next date in the array repeated 7 times.
As danludwig mentioned in his comment on the question, you are adding a reference for the same date to the array multiple times.
From the Moment.js documentation:
It should be noted that moments are mutable. Calling any of the manipulation methods will change the original moment.
If you want to create a copy and manipulate it, you should use moment#clone before manipulating the moment.
You should be calling the clone function on the Moment date object as shown here.
var startOfWeek = moment().startOf('week');
var endOfWeek = moment().endOf('week');
var days = [];
var day = startOfWeek;
while (day <= endOfWeek) {
days.push(day.toDate());
day = day.clone().add(1, 'd');
}
console.log(days);
As an aside:
You should not reference internal fields/functions of a 3rd party library. The name of these references are more likely to change than the public API described in the documentation. _d can be referenced by calling the public function toDate.

Categories