Moment not returning date range - javascript

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;
};

Related

Comparing Dates with Javascript does not work

Moment.js is driving me nuts.
I have dates in this format
10-Jul-2019 inside my array of objects alldata and here is my code:
I need to filter out the objects where DueDate is outside of the range of last 90 days.
The issue is that the comparisons is not working properly...it's telling me that
11-05-2019 > 08-08-2019
Am I missing something or is there a bug in moment.js? Feel free to suggest any method that does not use moment.js
var todate = moment().format("DD-MM-YYYY");
var fromdate = moment().subtract(90, "days").format("DD-MM-YYYY");
var data = [];
for (i = 0; i < alldata.length; i++) {
duedate = moment(alldata[i].DueDate, "DD-MMM-YYYY").format('DD-MM-YYYY');
if ( duedate >= fromdate) {
alert("good!");
} else
alert("bad!");
}
You are not comparing integers or numbers format returns a string.
Why not using the isAfter built-in method from moment.js library which compares two "moments".
var fromdate = new moment().subtract(90, "days");
for (i = 0; i < alldata.length; i++) {
let checkDate = new moment(alldata[i].DueDate,"DD-MMM-YYYY")
let isAfter = checkDate.isAfter(fromdate);
if ( isAfter ) {
alert("good!");
} else
alert("bad!");
}
You're comparing strings, because you're formatting the date before the compare.
This is a moment.js self-contained example:
//Include https://momentjs.com/downloads/moment.js
var oldDate = new moment('11-Jan-2018', 'DD-MMM-YYYY');
var newDate = new moment('01-Feb-2018', 'DD-MMM-YYYY');
if (newDate.isAfter(oldDate)) {
alert('it works');
}
else {
alert('no workie');
}
https://jsfiddle.net/h3yf5r60/4/
Use this snippet as an example for plain JS:
var now = new Date();
var yesterday = new Date();
yesterday.setMonth(yesterday.getMonth() - 1);
if (now > yesterday) {
alert('it works');
}
else {
alert('no workie');
}
https://jsfiddle.net/Lobpk519/

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));
}

Can't format using moment.js

I am trying to format a array of dates using moment.js but I get an error stating
dayOfWeek.format is not a function
I am correctly imported
var startOfWeek = moment().startOf('isoWeek');
var endOfWeek = moment().endOf('isoWeek');
var days = [];
var day = startOfWeek;
while (day <= endOfWeek) {
days.push(day.toDate());
day = day.clone().add(1, 'd');
}
var week = days.map(function(dayOfWeek, i){
console.log(dayOfWeek);
dayOfWeek.format("dddd, DD-MM-YYYY")
});
Your code will fail because dayOfWeek is not moment object.
To check if your variable is moment object use .isMoment:
moment.isMoment(dayOfWeek).
To fix your problem simply replace
dayOfWeek.format("dddd, DD-MM-YYYY")
with
moment(dayOfWeek).format("dddd, DD-MM-YYYY")
You are also missing return statement inside .map function.
Working example:
var startOfWeek = moment().startOf('isoWeek');
var endOfWeek = moment().endOf('isoWeek');
var days = [];
var day = startOfWeek;
while (day <= endOfWeek) {
days.push(day.toDate());
day = day.clone().add(1, 'd');
}
var week = days.map(function(dayOfWeek, i){
return moment(dayOfWeek).format("dddd, DD-MM-YYYY")
});
console.log(week);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
moment().format() function usage is not correct.
Current is:
dayOfWeek.format("dddd, DD-MM-YYYY")
Change to:
moment(dayOfWeek).format("dddd, DD-MM-YYYY")
Check here for more information: https://momentjs.com/docs/#/parsing/string-formats/
dayOfWeek = moment(dayOfWeek).format("dddd, DD-MM-YYYY");
Just a tip, You can also do this
var currentDate = moment(new Date()); // pass your date obj here.
console.log(currentDate.format('DD-MM-YY HH:mm:ss')); // later simply do this.
<script src="https://unpkg.com/moment#2.22.2/min/moment.min.js"></script>

How to loop through dates using for and while loops

I would like to be able to loop through an XML file to find the earliest and latest date. Once those dates are found, I want to loop through the records again and compare the month and year from each record to the date that is being passed in. If the month and year match, then the count is increased by one. After the loop goes through all of the records, the date and count are added to an array, the date being passed in is then increased by one, and the loops runs again. The while loop continues to run until the date being increased is greater than the latest record date.
MY CODE:
var record=xmlDoc.getElementsByTagName("record");
var maxDate = 0;
// Loop through all of the records to find the latest date
for(var i=0; i<record.length; i++)
{
var tempMaxDate = record[i].getElementsByTagName("visit_date")[0].childNodes[0].nodeValue;
if(tempMaxDate > maxDate)
{
maxDate = tempMaxDate;
}
}
var minDate = 99999999999999;
// Loop through all of the records to find the earliest date
for(var i=0; i<record.length; i++)
{
var tempMinDate = record[i].getElementsByTagName("visit_date")[0].childNodes[0].nodeValue;
if(tempMinDate < minDate)
{
minDate = tempMinDate;
}
}
var minDateGraph = minDate;
var count = 0;
var data = [];
// Loop until the minimum date is greater than the maximum
while(minDate <= maxDate)
{
var tempMinDate2 = new Date(0);
tempMinDate2.setMilliseconds(minDate);
minDate = tempMinDate2;
// Loop through all of the records
// If the month and year of minDate match the record then the count is increased
for(var i=0; i<record.length; i++)
{
var tempVisitDate = record[i].getElementsByTagName("visit_date")[0].childNodes[0].nodeValue;
var visitDate = new Date(0);
visitDate.setMilliseconds(tempVisitDate);
if((visitDate.getMonth() == minDate.getMonth()) && (visitDate.getFullYear() == minDate.getFullYear()))
{
count += 1;
}
}
var tempData = [minDate, count];
data.push(tempData);
var month = minDate.getMonth();
var year = minDate.getFullYear();
// Increase the minDate by one month
if(month == 12)
{
year += 1;
month = 1;
}
else
{
month += 1;
}
var tempMinDate3 = new Date(year, month, 1).getTime();
minDate = tempMinDate3;
}
The problem is when I run my current code, the browser crashes. I think I am running into an infinite loop, but I cannot find what is causing it. I would appreciate any suggestions. Thanks!

comparing dates in JavaScript using moment with langs

I have two dates namely newdate and haha. newdate will be today's date (current date) and haha date can be any.The below code is not working for me as i have provided
newdate : 07-Feb-2014 10:04
haha :03-Feb-2014 00:00
its always coming to else part
sdate:03-Feb-2014
stime :00:00
var haha=sdate+" "+stime;
var newdate=new Date();
var date_str = moment(newdate).format("DD-MMM-YYYY HH:mm");
alert(date_str);
if (Date.parse(haha) < Date.parse(date_str)) {
alert("Start date cannot be less than today's date");
return false;
}
else {
alert("hahahhahaha");
}
NOTE I am using moment with langs javscript
Your Code Works. Stime is formatted wrong remove the colon from in front of the first set of 00. stime 00:00. How are you generating stime this is the cause of you problem?
You can see my test here.
var sdate = "03-Feb-2014";
var stime = "00:00";
var haha = sdate + " " + stime;
var newdate = new Date();
if (navigator.appName.indexOf("Internet Explorer") != -1) {
alert("isIE");
var dateObject = (parseISO8601(haha));
var hahaDate = new Date(dateObject.year, dateObject.month, dateObject.day, dateObject.hour, dateObject.min);
alert(hahaDate);
if (hahaDate.getTime() < newdate.getTime()) {
alert("Start date cannot be less than today's date");
return false;
} else {
alert("hahahhahaha");
}
} else {
var date_str = moment(newdate).format("DD-MMM-YYYY HH:mm");
alert(date_str);
if (Date.parse(haha) < Date.parse(date_str)) {
alert("Start date cannot be less than today's date");
return false;
} else {
alert("hahahhahaha");
}
}
function parseISO8601(dateStringInRange) {
var dateAsObject = {};
var splitTimeFromDate = dateStringInRange.split(" ");
var splitTimeValues = splitTimeFromDate[1].split(":");
dateAsObject.hour = splitTimeValues[0];
dateAsObject.min = splitTimeValues[1];
var splitDate = splitTimeFromDate[0].split("-");
dateAsObject.year = splitDate[2];
dateAsObject.day = splitDate[0];
dateAsObject.month = monthToNum(splitDate[1]);
return dateAsObject;
}
function monthToNum(month) {
if (month == "Feb") return 1;
}
[Edit: Ok sorry I messed up with the Colon, If it fails at the else are you sure you unit tests include enough scenario to were the date is both greater than and less than the current date if it is only less than like your example you will never hit the code in the else. Again the code just works don't know what to say :-(, update example for both situations]
[Edit: Here is an example not complete you have to remember javascript is not universal. When you ask a question about JS assume as DEVs we all use Chrome or FF, or atleast post the browser(s) you tired. I provided a simple example of how I would accomplish this. Frankly I don't like external framework when I can do it myself so as you can see I am not using it feel free to do what you want the issue is cause by the way IE Parses DateTime you must use a more universal format like the one provided below. Example of possible formats: http://www.w3schools.com/jsref/jsref_obj_date.asp. Anyhow GL]
That is a bit convoluted, consider:
var newdate = new Date();
var date_str = moment(newdate).format("DD-MMM-YYYY HH:mm");
Date.parse(date_str);
if the above works (and there is absolutely no guarantee that Date.parse will correctly parse the string in all browsers in use), then all of that is equivalent to:
var newdate = new Date();
newdate.setSeconds(0, 0);
You would do very much better to manualy parse haha (or use moment.js since you have it already) and compare the resultant date objects.
Consider:
// s is dd-mmm-yyyy hh:mm
function stringToDate(s) {
s = s.split(/[- :]/);
var months = {'jan':0, 'feb':1, 'mar':2, 'apr':3, 'may':4, 'jun': 5,
'jul':6, 'aug':7, 'sep':8, 'oct':9, 'nov':10, 'dec':11};
return new Date(s[2], months[s[1].toLowerCase()], s[0], s[3], s[4], 0, 0);
}
var newdate = '07-Feb-2014 10:04';
var haha = '03-Feb-2014 00:00';
alert(stringToDate(newdate).getTime() == stringToDate(haha).getTime()); // false
// Set to same time
var newdate = '03-Feb-2014 00:00';
alert(stringToDate(newdate).getTime() == stringToDate(haha).getTime()); // true

Categories

Resources