is Javascript array.push method synchronous? - javascript

I am writing a simple javascript function but it is not as I have expected.
The following is the code:
var startDate = new Date('2015-07-01 00:00 +0800');
var endDate = new Date('2015-07-10 00:00 +0800');
var arrayOfDates = [];
if (endDate >= startDate) {
while (startDate < endDate) {
arrayOfDates.push(startDate);
startDate = new Date(startDate.setDate(startDate.getDate() + 1));
}
}
While I am expecting the result of arrayOfDates to be [2015-07-01, 2015-07-02, 2015-07-03.... , 2015-07-10']. The results is instead [2015-07-02, 2015-07-03.... , 2015-07-10']
Why is that? Is it somehow the var startDate is updated before the variable is pushed to the array? if that's the case how can I make sure the code is running synchronously?

When you call setDate(), that changes the date. All the setter functions on the Date prototype mutate the date instance.
You have to make a new date instance and then subsequently call the setter to change it.
startDate = new Date(startDate);
startDate.setDate(startDate().getDate() + 1);

It will do job for you and it wont change your date untill your current date is pushed:
var startDate = new Date('2015-07-01 00:00');
var endDate = new Date('2015-07-10 00:00');
var arrayOfDates = [];
if (endDate >= startDate) {
for(var dt = startDate; startDate < endDate; dt = new Date(startDate.setDate(startDate.getDate() + 1))){
console.log(startDate);
arrayOfDates.push(startDate);
}
}
Here you have fiddle https://jsfiddle.net/ggqzbn6h/

Related

Get dates list between 2 dates (fromDate and toDate) in utc time using angular7

I have try to get dates list between two date using JavaScript (I have already achieved in GMT).
Example:
fromDate - 2019-08-27
toDate - 2019-08-30
Date list
[2019-08-27, 2019-08-28, 2019-08-29, 2019-08-30]
I have already got this array using this following JavaScript
if(result.data.closurPeriods.length > 0) {
result.data.closurPeriods.forEach(closure => {
var start = closure.fromDate, //closure.fromDate = 2019-08-27
end = new Date(closure.toDate), //closure.toDate = 2019-08-30
currentDate = new Date(start);
while (currentDate <= end) {
this.closurPeriods.push(this.datePipe.transform(new Date(currentDate), 'yyyy-MM-dd'));
currentDate.setDate(currentDate.getDate() + 1);
}
});
}
The above JavaScript is working for only GTM and localtime(India). When I try to run this script in USA the date list array like this
[2019-08-28, 2019-08-28, 2019-08-29]
Because of UTC not accept this script.
My question is how to solve this above script in UTC
2019-08-27 is parsed as UTC, but getDate and setDate are local. The USA is west of Greenwich, so new Date('2019-08-27') produces a local date for 2019-08-26, adding a day makes it 2019-08-27.
The same thing will happen for any timezone that has a negative offset.
A simple fix is to use all UTC, e.g.:
function fillRange(start, end) {
let result = [start];
let a = new Date(start);
let b = new Date(end);
while (a < b) {
a.setUTCDate(a.getUTCDate() + 1);
result.push(a.toISOString().substr(0,10));
}
return result;
}
let from = '2019-08-27';
let to = '2019-08-30';
console.log(fillRange(from, to));
However, I'd advise explicitly parsing the date and not to use the built–in parser. A simple parse function is 2 or 3 lines of code, or you can use one of many parsing and formatting libraries.
Finally i got the solutions
var start = new Date(closure.fromDate); // 2019-07-27
var end = new Date(closure.toDate); // 2019-07-31
var currentDate = start;
while (currentDate <= end) {
//this.closurPeriods.push(this.datePipe.transform(new Date(currentDate), 'yyyy-MM-dd'));
var date = new Date(currentDate);
var datewithouttimezone = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
this.closurPeriods.push(this.datePipe.transform(new Date(datewithouttimezone), 'yyyy-MM-dd'));
currentDate.setDate(currentDate.getDate() + 1);
}
Or
var start = new Date(closure.fromDate); // 2019-07-27
var end = new Date(closure.toDate); // 2019-07-31
var currentDate = start;
while (start < end) {
start.setUTCDate(start.getUTCDate() + 1);
this.closurPeriods.push(start.toISOString().substr(0, 10));
}

Moment not returning date range

I am trying to create a date array between 2 dates.
[11/16/2018, 12/16/2018, 1/16/2019......11/16/2019]
I have the following code.
function dateRange(stDate, etDate) {
const dates = [];
var startDate = moment(new Date(stDate)).format("MM/DD/YYYY");
var endDate = moment(new Date(etDate)).format("MM/DD/YYYY");
var now = new Date(startDate);
while (startDate <= endDate) {
dates.push(new Date(now));
now = now.addMonths(1);
}
console.log("dateRange " + dates);
}
function RunLedgerAndPV() {
var stDate = "11/16/2018";
var etDate = "11/16/2019";
dateRange(stDate, etDate);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
Trying to debug it, it doesn't break or anything and it is returning the just the start and end date but doesn't push the date array. What am i doing wrong here?
Also, i have looked at the other posts regarding this and i have myself worked on date range in the past. However, i am clueless as to why this isn't working for me.
Any help is appreciated. Thank you!
There are quite a few inefficiencies and bugs in your code, too many to list really. A summary would include unnecessary creation and then re-stringifying of dates, unnecessary use of JS Date constructors and dodgy logic in your for loop.
Here's a version which will work correctly using just momentJS functionality:
function createLedger(stDate, etDate) {
if (stDate && etDate) {
var endOfLeaseDate = moment(etDate, "MM/DD/YYYY");
var startOfLeaseDate = moment(stDate, "MM/DD/YYYY");
dateRange(startOfLeaseDate, endOfLeaseDate);
}
}
function dateRange(stDate, etDate) {
var dates = [];
var now = stDate.clone();
var day = stDate.date();
while(now.isBefore(etDate)) {
//deal with variable month end days
var monthEnd = now.clone().endOf("month");
if (now.date() < day && day <= monthEnd.date()) { now.date(day); }
dates.push(now.format("YYYY-MM-DD"));
now = now.clone().add({ "months" : 1 });
}
console.log(dates);
}
function RunLedgerAndPV() {
var stDate = "12/31/2018";
var etDate = "12/31/2019";
createLedger(stDate, etDate);
}
RunLedgerAndPV();
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
for (var i=0; now <= endDate; i++) {
dates.push(new Date(now));
now = now.addMonths(1);
}
you instantiate and use i in order to loop through nothing. the condition now <= endDate is in no way affected by the value of i ( typically you increment / decrement i until it reaches the desired value as : var i=0; i < 11; i++ ) i dont event know how this would work, my first instinct is that it will generate a loop that wont stop until until we reach that endDate date.
You seems to be looking for getting all the date between a specific range, try the following :
var enumerateDaysBetweenDates = function(startDate, endDate) {
var dates = [];
var currDate = moment(startDate, 'MM/DD/YYYY');;
var lastDate = moment(endDate, 'MM/DD/YYYY');;
while(currDate.add(1, 'months').diff(lastDate) < 0) {
console.log(currDate.toDate());
dates.push(currDate.clone().toDate());
}
return dates;
};

Moment.js while loop in javascript, node.js

The code supposes to fill the array with dates between given start and end dates. I am using Node.js.
var startDate = moment(startDay);
var endDate = moment(endDay);
var datesBetween = [];
var startingMoment = startDate;
while(startingMoment <= endDate) {
datesBetween.push(startingMoment);
startingMoment.add(1, 'days');
}
console.log(datesBetween);
You need to create a new object each iteration otherwise you are pushing the same object reference into array each time. They will all end up with last date since it is all the same object
You can use moment.clone() to clone the object each time
var startDay = new Date(2018,1,1);
var endDay = new Date(2018,1,4);
var startDate = moment(startDay);
var endDate = moment(endDay);
var datesBetween = [];
var startingMoment = startDate;
while(startingMoment <= endDate) {
datesBetween.push(startingMoment.clone());// clone to add new object
startingMoment.add(1, 'days');
}
console.log(datesBetween);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.0/moment.min.js"></script>

How to get new array between selected two dates using javascript array

My javascript array like that. var datearray = ["2010-01-10","2010-01-20","2014-01-35","2014-10-22","2014-03-02","2010-02-11","2010-03-18","2010-09-09","2014-11-12","2014-02-23","2014-03-02","2014-03-02","2014-04-22","2014-05-09","2014-02-23","","2010-02-19","2010-03-01","2010-02-27","2010-02-25"];
but my searching dates are startDate = 2010-01-01; and endDate = 2010-03-29; I want to get new date array between above startDate and endDate; How I created It.
var dateArray = ["2010-01-10","2010-01-20","2014-01-35","2014-10-22","2014-03-02","2010-02-11","2010-03-18","2010-09-09","2014-11-12","2014-02-23","2014-03-02","2014-03-02","2014-04-22","2014-05-09","2014-02-23","","2010-02-19","2010-03-01","2010-02-27","2010-02-25"],
startDate = Date.parse("2010-01-01"),
endDate = Date.parse("2010-03-29");
var filteredDateArray = dateArray.filter(function(s) {
s = Date.parse(s);
return s > startDate && s < endDate;
});
console.log(filteredDateArray);

Check if a date within in range

I am trying to check if a date of format mm.dd.yyyy is greater than today and less than the date after 6 months from today.
Here is my code:
var isLinkExpiryDateWithinRange = function(value) {
var monthfield = value.split('.')[0];
var dayfield = value.split('.')[1];
var yearfield = value.split('.')[2];
var inputDate = new Date(yearfield, monthfield - 1, dayfield);
var today = new Date();
today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
alert(inputDate > today);//alert-> true
var endDate = today;
endDate.setMonth(endDate.getMonth() + 6);
alert(inputDate > today);//alert-> false
if(inputDate > today && inputDate < endDate) {
alert('1');
} else {
alert('2');/always alert it
}
}
If I execute isLinkExpiryDateWithinRange('12.08.2012') I wish it will show 1 as this is within the range, but it is displaying 2. Moreover the first alert is showing true and the second one false.
Can anyone please explain what is happening?
Change:
var endDate = today;
to:
var endDate = new Date(today);
See the posts here for how objects are referenced and changed. There are some really good examples that help explain the issue, notably:
Instead, the situation is that the item passed in is passed by value.
But the item that is passed by value is itself a reference.
JSFiddle example
function isLinkExpiryDateWithinRange( value ) {
// format: mm.dd.yyyy;
value = value.split(".");
var todayDate = new Date(),
endDate = new Date( todayDate.getFullYear(), todayDate.getMonth() + 6, todayDate.getDate() +1 );
date = new Date(value[2], value[0]-1, value[1]);
return todayDate < date && date < endDate;
}
isLinkExpiryDateWithinRange("12.24.2012"); // true
isLinkExpiryDateWithinRange("12.24.2020"); // false
Below function checks if date selected is within 5 days from today. Date format used is "DD-MM-YYYY", you can use any format by changing value.split('-')[1] order and split character.
function showMessage() {
var value = document.getElementById("invoiceDueDate").value;
var inputDate = new Date(value.split('-')[2], value.split('-')[1] - 1, value.split('-')[0]);
var endDate = new Date();
endDate.setDate(endDate.getDate() + 5);// adding 5 days from today
if(inputDate < endDate) {
alert("If the due date selected for the invoice is within 5 days, and express settlement fee will apply to this transaction.");
}
}

Categories

Resources