Create array of dates from starting date in JavaScript and React - javascript

I have a React component where I have a date string from which I need to generate an array of dates representing the next 11 days excluding the starting date (10/12/2016). Not sure how to achieve this. That's what I've tried so far but the problem is that by simply looping adding 1 for each iteration on the day, it won't generate the correct date when the date range of 11 days spans between two months:
addDays = () => {
const { startDate } = this.props.pageData.parcelDetails.parcelDetails;
const date = new Date(startDate);
let datesCollection = []
for (var i = 1; i < 12; i++) {
datesCollection.push(`${date.getDate() + i}/${date.getMonth() + 1}/${date.getFullYear()}`)
}
return datesCollection
}
The code above generates the following array:
[
"11/12/2016",
"12/12/2016",
"13/12/2016",
"14/12/2016",
"15/12/2016",
"16/12/2016",
"17/12/2016",
"18/12/2016",
"19/11/2016",
"20/12/2016",
"21/12/2016"
]
How do I generate the correct array, with proper dates for each month?

You can simply do that:
addDays = () => {
const { startDate } = this.props.pageData.parcelDetails.parcelDetails;
const date = new Date(startDate);
let datesCollection = []
for (var i = 1; i < 12; i++) {
const newDate = new Date(date.getTime() + i * 1000 * 60 * 60 * 24);
datesCollection.push(`${newDate.getDate()}/${newDate.getMonth() + 1}/${newDate.getFullYear()}`);
}
return datesCollection
}

You can try adding 1 day to each loop.
var dateuse = new Date();
dateuse.setDate(dateuse.getDate() + 1);
or you can try Moment.js
var today = moment();
var dateuse = moment(today).add(1, 'days');

Related

Converting date array with getTime()

this is a snippet of code from a project I am doing, I have to convert dates using to getTime() function and push them into a new array, however everytime i do however the new array prints as NaN, i was hoping to gain some insight on what i was doing wrong and how to fix this issue. Thanks a ton :)
dates = ["28/7/2020", "28/3/2020", "28/1/2020", "28/10/2020"]
// const MAX = dates[0]
// const MIN = dates[dates.length - 1];
const dateArr = [];
const DAY_IN_MS = 24 * 60 * 60 * 1000
for (i = 0; i < dates.length; i++) {
d = new Date(dates[i])
dateInMs = d.getTime();
parseInt(dateInMs);
console.log(dateInMs);
dateArr.push(dateInMs);
}
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
</body>
</html>
you have to switch the day and month otherwise new Date will return invalid date
example:
const d = "28/7/2020";
const dateSplit = d.split("/")
new Date(`${dateSplit[1]}/${dateSplit[0]}/${dateSplit[2]}`)
will return: Tue Jul 28 2020 00:00:00 GMT+0200 (Central European Summer Time)
What you could do is replace your New date line with the following:
const dateSplit = dates[i].split("/")
const newDate = new Date(`${dateSplit[1]}/${dateSplit[0]}/${dateSplit[2]}`)
d = new Date(newDate)
Either that or try to change the initial format to something new Date can Handle. This will prevent of having to split and add extra code
EDIT: To get the amount of days between first and last date. Here is an example:
const minutes = 1000*60;
const hours = minutes*60;
const days = hours*24;
const date1 = new Date("7/28/2020").getTime();
const date2 = new Date("10/28/2020").getTime();
const dateDiff = Math.round((date2 - date1)/days);
console.log(dateDiff);
EDIT 2: to get the difference in length you would do this (using the dates you mentioned in your comment):
const dateArr = [];
let date1 = ("23/9/2020").split("/");
let date2 = ("29/9/2020").split("/");
const diffDays = date2[0] - date1[0]; // date1[0] = 23, date2[0] = 29
for (i = 0; i <= diffDays; i++) {
// content of the push would save each day between 23 and 29 as value... you can put whatever in here
dateArr.push(`${date1[0] + i}/9/2020`);
}
console.log(dateArr.length); // should equal 7
3 lines in your javascript code are missing semicolons. My suggestion is to review your code a bit more carefully before posting, and also review the syntax for the various javascript date functions. This should work:
const dates = ["28/7/2020", "28/3/2020", "28/1/2020", "28/10/2020"];
var dateArr = [];
var DAY_IN_MS = 24 * 60 * 60 * 1000;
for (i = 0; i < dates.length; i++) {
// format your date string properly for Date()
var tmp = dates[i].split('/');
// convert the string to a date
var d = new Date( tmp[2], tmp[1], tmp[0] );
console.log( dates[i] );
console.log( d );
dateInMs = d.getTime();
parseInt(dateInMs);
console.log(dateInMs);
dateArr.push(dateInMs);
}

How to get minutes in between two different dates?

Hi i am using Javascript and i want to get each and every minute between two dates for example:
firstDate: 2019-04-02 02:03:00
secondDate: 2019-04-03 03:04:00
So my final output result should return like this:
2019-04-02 02:03:00
2019-04-02 02:04:00
2019-04-02 02:05:00
.
.
.
2019-04-03 03:04:00
Here is the code which i tried
var boxingDay = new Date("2019-04-02 02:03:00");
var nextWeek = new Date("2019-04-03 03:04:00");
function getDatesRange(startDate, stopDate){
const ONE_DAY = 60*1000;
var days= [];
var currentDate = new Date(startDate);
while (currentDate <= stopDate) {
days.push(new Date (currentDate));
currentDate = currentDate - 1 + 1 + ONE_DAY;
}
return days.join("\n");
}
console.log(getDatesRange(boxingDay,nextWeek))
/* var map = getDates(boxingDay, nextWeek).map((times) => {
console.log(Date.parse(times))
}) */
/* console.log((getDates( boxingDay, nextWeek ))); */
The problem is I am getting correct output but I need in the form of an array, like below and reuse the function if I am reusing, it returns me an empty array.
[[2019-04-02 02:03:00],[2019-04-02 02:04:00].....]
Any solution TIA.
Using your code as a basis, you can do this as follows (note that I'm using .toISOString(), you can change this according to your needs):
const boxingDay = new Date("2019-04-02 02:03:00");
const nextWeek = new Date("2019-04-03 03:04:00");
function getDatesRange(startDate, stopDate){
const ONE_MINUTE = 60*1000;
const days= [];
let currentDate = new Date(startDate);
while (currentDate <= stopDate) {
days.push([currentDate.toISOString()]);
currentDate.setTime(currentDate.getTime() + ONE_MINUTE);
}
return days;
}
console.log(getDatesRange(boxingDay,nextWeek));
There is a way, that you could use while loop with format function, each iteration increate the minute
const firstDate = new Date('2019-04-02 02:03:00')
const secondDate = new Date('2019-04-03 03:04:00')
const formatDate = dateObj => {
const year = String(dateObj.getFullYear()).padStart(4, '0')
const month = String(dateObj.getMonth() + 1).padStart(2, '0')
const date = String(dateObj.getDate()).padStart(2, '0')
const hour = String(dateObj.getHours()).padStart(2, '0')
const minute = String(dateObj.getMinutes()).padStart(2, '0')
const second = String(dateObj.getSeconds()).padStart(2, '0')
return `${year}-${month}-${date} ${hour}:${minute}:${second}`
}
const res = []
const iteratedDate = new Date(firstDate.getTime())
while (iteratedDate <= secondDate) {
res.push(formatDate(iteratedDate))
iteratedDate.setMinutes(iteratedDate.getMinutes() + 1)
}
// res array is large so I sliced the first 10 amd the last 10
console.log(res.slice(0, 10))
console.log(res.slice(res.length - 10))
A slightly different approach using a for loop; it also avoids creating a new Date instance for each minute iterated.
const p = new Date("2019-04-02T23:57:00");
const q = new Date("2019-04-03T00:03:00");
const r = [];
for(const d = new Date(p); d <= q; d.setTime(d.getTime() + 60000))
{
r.push(d.toISOString().substring(0, 19).replace(/T/, " "));
}
const s = r.join("\n");
console.log(s);

Creating an array of dates between 2 dates

I have 2 dates: startdate and enddate. End date is always a day less than the startdate. So if my start day is 19th, the end date would be on the 18th of next month.
I am trying to create an array of number of days in between the 2 dates.
(It goes from 19th to 18th and then 18th to 18th of every month to calculate the difference)
Example
8/19/2018 - 9/18/2018 = 30 days
9/18/2018 - 10/18/2019 = 30 days
10/18/2018 - 11/18/2018 = 31 days
array = [30,30,31]
I am using the following code to calculate days difference between the dates.
function daysBetweenArrears (date1, date2){
date1.setDate(date1.getDate() );
date2.setDate(date2.getDate() - 1);
var Diff = Math.abs(date2.getTime() - date1.getTime());
var TimeDifference = Math.round(Diff / (1000 * 3600 * 24));
return TimeDifference;
}
The following code for creating the array
if (document.getElementById("endDate"))
y = document.getElementById("endDate").value;
if (document.getElementById("startDate"))
z = document.getElementById("startDate").value;
var dateArr = getDateArray(z, y);
var dayCountArr = "";
var b = [];
for (var x = 0; x < dateArr.length-1; x++)
{
dayCountArr += daysBetweenArrears(dateArr[x], dateArr[x+1], ",");
b.push(daysBetweenArrears(dateArr[x], dateArr[x+1]));
}
The issue is that when i set the date as following, it is giving me incorrect output. The problem is that it is setting the dates incorrectly whenever it goes to the next month. I am not sure what i am doing wrong here. Any help is greatly appreciated. Thank you.
date2.setDate(date2.getDate() - 1);
You can do this using moment. Hope this helps.
const start = "8/19/2018";
const end = "11/18/2018 ";
const dates = [];
const mstart = moment(new Date(start));
const mend = moment(new Date(end));
for (let i = 0; mstart < mend ; i++) {
const daysInMonth = mstart.daysInMonth() + (i === 0 ? -1 : 0);
dates.push(daysInMonth);
mstart.add(1, 'M');
}
console.log(dates);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
You can update your function daysBetweenArrears
const daysBetweenArrears = (date1, date2) => {
const time1 = new Date(date1).getTime();
const time2 = new Date(date2).getTime();
const diff = Math.abs(time2 - time1);
return Math.round(diff/(1000*60*60*24));
};
console.log(daysBetweenArrears('8/18/2018', '9/18/2018'));
console.log(daysBetweenArrears('6/18/2018', '7/18/2018'));

How can I use moment.js to add days, excluding weekends?

I'm setting a default follow-up date two days from current date, which currently works:
const Notify = moment().add(2, 'days').toDate();
However, I would like to exclude weekends. So I installed moment WeekDay, but I can't seem to get it to work with adding days to the current date. The documentation calls for:
moment().weekday(0)
But I can't get that to work with adding in two days forward. Any ideas?
This solution is simple, easy to follow, and works well for me:
function addBusinessDays(originalDate, numDaysToAdd) {
const Sunday = 0;
const Saturday = 6;
let daysRemaining = numDaysToAdd;
const newDate = originalDate.clone();
while (daysRemaining > 0) {
newDate.add(1, 'days');
if (newDate.day() !== Sunday && newDate.day() !== Saturday) {
daysRemaining--;
}
}
return newDate;
}
Try: moment-business-days
It should help you.
Example:
var momentBusinessDays = require("moment-business-days")
momentBusinessDays('20-09-2018', 'DD-MM-YYYY').businessAdd(3)._d
Result:
Tue Sep 25 2018 00:00:00 GMT+0530 (IST)
You could also not use external lib and do a simple function like one of these two:
const WEEKEND = [moment().day("Saturday").weekday(), moment().day("Sunday").weekday()]
const addBusinessDays1 = (date, daysToAdd) => {
var daysAdded = 0,
momentDate = moment(new Date(date));
while (daysAdded < daysToAdd) {
momentDate = momentDate.add(1, 'days');
if (!WEEKEND.includes(momentDate.weekday())) {
daysAdded++
}
}
return momentDate;
}
console.log(addBusinessDays1(new Date(), 7).format('MM/DD/YYYY'))
console.log(addBusinessDays1('09-20-2018', 3).format('MM/DD/YYYY'))
// This is the somewhat faster version
const addBusinessDays2 = (date, days) => {
var d = moment(new Date(date)).add(Math.floor(days / 5) * 7, 'd');
var remaining = days % 5;
while (remaining) {
d.add(1, 'd');
if (d.day() !== 0 && d.day() !== 6)
remaining--;
}
return d;
};
console.log(addBusinessDays2(new Date(), 7).format('MM/DD/YYYY'))
console.log(addBusinessDays2('09-20-2018', 3).format('MM/DD/YYYY'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
They are slightly modified from this post and I think are a good alternative to external library you have to carry/deal with (assuming this is the only part you need and not other features of that lib).
This will do it based on any starting date, and without a costly loop. You calculate the number of weekend days you need to skip over, then just offset by the number of weekdays and weekends, together.
function addWeekdays(year, month, day, numberOfWeekdays) {
var originalDate = year + '-' + month + '-' + day;
var futureDate = moment(originalDate);
var currentDayOfWeek = futureDate.day(); // 0 = Sunday, 1 = Monday, ..., 6 = Saturday
var numberOfWeekends = Math.floor((currentDayOfWeek + numberOfWeekdays - 1) / 5); // calculate the number of weekends to skip over
futureDate.add(numberOfWeekdays + numberOfWeekends * 2, 'days'); // account for the 2 days per weekend
return futureDate;
}
const addWorkingDays = (date: Moment, days: number) => {
let newDate = date.clone();
for (let i = 0; i < days; i++) {
if (newDate.isoWeekday() !== 6 && newDate.isoWeekday() !== 7) {
newDate = newDate.add(1, "days");
} else {
newDate = newDate.add(1, "days");
i--;
}
}
return newDate.format("YYYY/MM/DD");
};
var moment = require("moment")
function addWorkingDay(date, days){
let daysToAdd = days
const today = moment(date);
const nextWeekStart = today.clone().add(1, 'week').weekday(1);
const weekEnd = today.clone().weekday(5);
const daysTillWeekEnd = Math.max(0, weekEnd.diff(today, 'days'));
if(daysTillWeekEnd >= daysToAdd) return today.clone().add(daysToAdd, 'days');
daysToAdd = daysToAdd - daysTillWeekEnd - 1;
return nextWeekStart.add(Math.floor(daysToAdd/5), 'week').add(daysToAdd % 5, 'days')
}
I think this code will be faster:
var businessDays = 10;
var days = businessDays + Math.floor((Math.min(moment().day(),5)+businessDays)/6)*2;
moment.add(days, 'days');
// using pure JS
function addBusinessDays(originalDate, numDaysToAdd) {
const Sunday = 0;
const Saturday = 6;
let daysRemaining = numDaysToAdd;
const newDate = originalDate;
while (daysRemaining > 0) {
newDate.setDate(newDate.getDate() + 1);
if (newDate.getDay() !== 0 && newDate.getDay() !== 6) {
// skip sunday & saturday
daysRemaining--;
}
}
return newDate;
}
var dt = new Date(); // get date
var business_days = 8;
newDate = addBusinessDays(dt, business_days);
console.log(newDate.toString());

Get a list of dates between two dates using javascript

From JavaScript is there a way to get list of days between two dates from MySQL format. I don't want to use any library for this.
This is what i did.
function generateDateList(from, to) {
var getDate = function(date) { //Mysql Format
var m = date.getMonth(), d = date.getDate();
return date.getFullYear() + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d);
}
var fs = from.split('-'), startDate = new Date(fs[0], fs[1], fs[2]), result = [getDate(startDate)], start = startDate.getTime(), ts, end;
if ( typeof to == 'undefined') {
end = new Date().getTime();
} else {
ts = to.split('-');
end = new Date(ts[0], ts[1], ts[2]).getTime();
}
while (start < end) {
start += 86400000;
startDate.setTime(start);
result.push(getDate(startDate));
}
return result;
}
console.log(generateDateList('2014-2-27', '2014-3-2'));
I test it from chrome and nodejs below are the result.
[ '2014-02-27',
'2014-02-28',
'2014-02-29',
'2014-02-30',
'2014-02-31',
'2014-03-01',
'2014-03-02' ]
yeh big leap year:-D..., how can i fix this? or is there any better way.?
const listDate = [];
const startDate ='2017-02-01';
const endDate = '2017-02-10';
const dateMove = new Date(startDate);
let strDate = startDate;
while (strDate < endDate) {
strDate = dateMove.toISOString().slice(0, 10);
listDate.push(strDate);
dateMove.setDate(dateMove.getDate() + 1);
};
Take the start date and increment it by one day until you reach the end date.
Note: MySQL dates are standard format, no need to parse it by hand just pass it to the Date constructor: new Date('2008-06-13').
const addDays = (date, days = 1) => {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
};
const dateRange = (start, end, range = []) => {
if (start > end) return range;
const next = addDays(start, 1);
return dateRange(next, end, [...range, start]);
};
const range = dateRange(new Date("2014-02-27"), new Date("2014-03-02"));
console.log(range);
console.log(range.map(date => date.toISOString().slice(0, 10)))
Here I use a recursive function, but you could achieve the same thing using a while (see other answers).
I have used this one from
https://flaviocopes.com/how-to-get-days-between-dates-javascript/
const getDatesBetweenDates = (startDate, endDate) => {
let dates = []
//to avoid modifying the original date
const theDate = new Date(startDate)
while (theDate < new Date(endDate)) {
dates = [...dates, new Date(theDate)]
theDate.setDate(theDate.getDate() + 1)
}
dates = [...dates, new Date(endDate)]
return dates
}
Invoke the function as follows:
getDatesBetweenDates("2021-12-28", "2021-03-01")
Note - I just had to fix issues with the Date object creation (new Date()) in the while loop and in the dates array. Other than that the code is pretty much same as seen on the above link
dateRange(startDate, endDate) {
var start = startDate.split('-');
var end = endDate.split('-');
var startYear = parseInt(start[0]);
var endYear = parseInt(end[0]);
var dates = [];
for(var i = startYear; i <= endYear; i++) {
var endMonth = i != endYear ? 11 : parseInt(end[1]) - 1;
var startMon = i === startYear ? parseInt(start[1])-1 : 0;
for(var j = startMon; j <= endMonth; j = j > 12 ? j % 12 || 11 : j+1) {
var month = j+1;
var displayMonth = month < 10 ? '0'+month : month;
dates.push([i, displayMonth, '01'].join('-'));
}
}
return dates;
}
var oDate1 = oEvent.getParameter("from"),
oDate2 = oEvent.getParameter("to");
var aDates = [];
var currentDate = oDate1;
while (currentDate <= oDate2) {
aDates.push(new Date(currentDate));
currentDate.setDate(currentDate.getDate() + 1);
}
I expanded Công Thắng's great answer to return {years, months, days}, thought it was worth sharing:
function getDates(startDate, endDate) {
const days = [],
months = new Set(),
years = new Set()
const dateMove = new Date(startDate)
let date = startDate
while (date < endDate){
date = dateMove.toISOString().slice(0,10)
months.add(date.slice(0, 7))
years.add(date.slice(0, 4))
days.push(date)
dateMove.setDate(dateMove.getDate()+1) // increment day
}
return {years: [...years], months: [...months], days} // return arrays
}
console.log(getDates('2016-02-28', '2016-03-01')) // leap year
/* =>
{
years: [ '2016' ],
months: [ '2016-02', '2016-03' ],
days: [ '2016-02-28', '2016-02-29', '2016-03-01' ]
}
*/
const {months} = getDates('2016-02-28', '2016-03-01') // get only months
Basically the function just increments the built-in Date object by one day from start to end, while the Sets capture unique months and years.

Categories

Resources