Generate date range given date from and to - javascript

I have an array of object:
[{from:'2017-05-02',to:'2017-05-12',event:'google map launch day'},
{from:'2017-05-03',to:'2017-05-14',event:'marie"s farewell'},
{from:'2017-05-20',to:'2017-05-20',event:'iphone showcase'}]
I want to map the event property to array of object below
[{
date: "2017-05-01"
},
{
date: "2017-05-02",
event: ['google map launch day']
},
{
date: "2017-05-03",
event: ['google map launch day', 'marie"s farewell']
},
{
date: "2017-05-04",
event: ['google map launch day', 'marie"s farewell']
}
..
]
https://pastebin.com/raw/Uv3U8zCy
I have no control over the first array of object, it came from an external API, I want to build a custom calendar, I'm struggling to map to a new format of array of object.
function generateDates(startDate, stopDate) {
var dateArray = [];
var currentDate = moment(startDate);
var stopDate = moment(stopDate);
while (currentDate <= stopDate) {
dateArray.push({ date: moment(currentDate).format('YYYY-MM-DD') });
currentDate = moment(currentDate).add(1, 'days');
}
return dateArray;
}
generateDates('2017-05-01', '2017-05-31');
I'm able to generate days of a month using momentjs but I'm still stuck.

You can use .isBetween of moment.js and get Events from iterating date as below.
var eventData = [{from:'2017-05-02',to:'2017-05-12',event:'google map launch day'},
{from:'2017-05-03',to:'2017-05-14',event:'marie"s farewell'},
{from:'2017-05-20',to:'2017-05-20',event:'iphone showcase'}]
// Get events for passed date
function getEvents(curDate){
return eventData.reduce(function(res,obj){
if(moment(curDate).isBetween(obj.from, obj.to, null, '[]'))
res.push(obj.event);
return res;
},[])
}
function generateDates(startDate, stopDate) {
var dateArray = [];
var dateArray = [];
var currentDate = moment(startDate);
var stopDate = moment(stopDate);
while (currentDate <= stopDate) {
dateArray.push({
date: moment(currentDate).format('YYYY-MM-DD'),
event:getEvents(currentDate) // Get events array here
});
currentDate = moment(currentDate).add(1, 'days');
}
return dateArray;
}

You could use a hash table as reference to the generated dates and iterate later in the same style the events.
function getRanges(data, startDate, stopDate) {
function generateDates(startDate, stopDate) {
var currentDate = moment(startDate),
stopDate = moment(stopDate),
date;
while (currentDate <= stopDate) {
date = moment(currentDate).format('YYYY-MM-DD');
hash[date] = { date: date };
dateArray.push(hash[date]);
currentDate = moment(currentDate).add(1, 'days');
}
}
var dateArray = [],
hash = {};
generateDates(startDate, stopDate);
data.forEach(function (a) {
var currentDate = moment(a.from),
stopDate = moment(a.to),
date;
while (currentDate <= stopDate) {
date = moment(currentDate).format('YYYY-MM-DD');
hash[date].event = hash[date].event || [];
hash[date].event.push(a.event);
currentDate = moment(currentDate).add(1, 'days');
}
});
return dateArray;
}
var data = [{ from: '2017-05-02', to: '2017-05-12', event: 'google map launch day' }, { from: '2017-05-03', to: '2017-05-14', event: 'marie"s farewell' }, { from: '2017-05-20', to: '2017-05-20', event: 'iphone showcase' }];
console.log(getRanges(data, '2017-05-01', '2017-05-31'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.2/moment.min.js"></script>

Related

Why my code don't compare correctly dates?

I would like to check does the date fall within the range.
I create two functions, first func transforms type str to Date,second func must find result.
let probeArray = [{price: 123, date: '2021-11-27'},
{price: 13, date: '2021-11-15'},
{price: 1, date: '2021-10-2'},
{price: 17, date: '2021-10-1'}];
let startDate = '2021-10-1';
let endDate = '2021-10-20';
// transform str to Date
const toDate = (dateStr) => {
const [year,month,day] = dateStr.split("-");
// console.log('check date')
// console.log([day, month, year])
return new Date(year, month - 1, +day+1);
}
function get_staticstic(probeAr, start, end){
let result = null;
let maxDate = toDate(start);
let minDate = toDate(end);
for (let tempEvent of probeAr){
let currentDate = toDate(tempEvent.date);
console.log('maxDate', maxDate);
console.log('minDate', minDate);
console.log('currentDate',currentDate);
if (currentDate >= minDate && currentDate <= maxDate ){
console.log('Correct Date');
}
else{
console.log('Out Side range!!');
}
}
return result
}
get_staticstic(probeArray, startDate, endDate);
But after start result for all dates is 'Out Side range!!'.
Issue with code
Error in toDate function. Defition should be return new Date(year, +month - 1, day);. No need to add 1 with date. Also its not mandatory for the year and day to be number, they can be string aswell.
Error with minDate and maxDate inside get_staticstic.
Working Fiddle
let probeArray = [
{ price: 123, date: '2021-11-27' },
{ price: 13, date: '2021-11-15' },
{ price: 1, date: '2021-10-2' },
{ price: 17, date: '2021-10-1' }
];
let startDate = '2021-10-1';
let endDate = '2021-10-20';
// transform str to Date
const toDate = (dateStr) => {
const [year, month, day] = dateStr.split("-");
// console.log('check date')
// console.log([day, month, year])
return new Date(year, +month - 1, day);
}
function get_staticstic(probeAr, start, end) {
let result = null;
let minDate = toDate(start);
let maxDate = toDate(end);
console.log('maxDate', maxDate);
console.log('minDate', minDate);
for (let tempEvent of probeAr) {
let currentDate = toDate(tempEvent.date);
console.log('currentDate', currentDate);
if (currentDate >= minDate && currentDate <= maxDate) {
console.log('Correct Date');
}
else {
console.log('Out Side range!!');
}
}
return result
}
get_staticstic(probeArray, startDate, endDate);
Better Approach
Since all date strings ae in standard format, you dont need to write a parser function for date. You can directly convert to date object using new Date(dateString) method.
Working Fiddle
let probeArray = [
{ price: 123, date: '2021-11-27' },
{ price: 13, date: '2021-11-15' },
{ price: 1, date: '2021-10-2' },
{ price: 17, date: '2021-10-1' }
];
let startDate = '2021-10-1';
let endDate = '2021-10-20';
function get_staticstic(probeAr, start, end) {
let result = null;
let minDate = new Date(start);
let maxDate = new Date(end);
console.log('maxDate', maxDate);
console.log('minDate', minDate);
for (let tempEvent of probeAr) {
let currentDate = new Date(tempEvent.date);
console.log('currentDate', currentDate);
if (currentDate >= minDate && currentDate <= maxDate) {
console.log('Correct Date');
}
else {
console.log('Out Side range!!');
}
}
return result
}
get_staticstic(probeArray, startDate, endDate);
You should set minDate to the start date and maxDate to the end date. You did the opposite.
let probeArray = [{price: 123, date: '2021-11-27'},
{price: 13, date: '2021-11-15'},
{price: 1, date: '2021-10-2'},
{price: 17, date: '2021-10-1'}];
let startDate = '2021-10-1';
let endDate = '2021-10-20';
// transform str to Date
const toDate = (dateStr) => {
const [year,month,day] = dateStr.split("-");
// console.log('check date')
// console.log([day, month, year])
return new Date(year, month - 1, +day+1);
}
function get_statistic(probeAr, start, end){
let result = null;
let minDate = toDate(start);
let maxDate = toDate(end);
for (let tempEvent of probeAr){
let currentDate = toDate(tempEvent.date);
console.log('maxDate', maxDate);
console.log('minDate', minDate);
console.log('currentDate',currentDate);
if (currentDate >= minDate && currentDate <= maxDate ){
console.log('Correct Date');
}
else{
console.log('Out Side range!!');
}
}
return result
}
get_statistic(probeArray, startDate, endDate);

Filter an array of objects by date that > than date.now

I'm having some problems with arrow functions and filtering array of objects by value of date.
I've tried to filter it but it returns full array, and did'nt working as it must be.
in the end i've got to return items - objects in array which expiration date is bigger than today. It must be arrow function
const menuItems = [{
name: 'Hamburger',
expirationDate: '09-24-2019'
},
{
name: 'Chicken',
expirationDate: '10-03-2019'
},
{
name: 'Hot-Dog',
expirationDate: '03-24-2019'
},
];
let today = new Date();
let dd = today.getDate();
let mm = today.getMonth();
let yyyy = today.getFullYear();
if (dd < 10) {
dd = '0' + dd;
}
if (mm < 10) {
mm = '0' + mm;
}
today = mm + '-' + dd + '-' + yyyy;
console.log(today);
const filterByExpiration = (items) => {
menuItems.filter(function() {
return items.expirationDate > today;
})
};
That's doing lexicographical comparison - not what you want. Just compare the two Dates together - and using an arrow function means you can also have an implicit return
const menuItems = [{name:'Hamburger',expirationDate:'09-24-2019'},{name:'Pizza',expirationDate:'03-11-2019'},{name:'Sushi',expirationDate:'03-21-2019'},{name:'Chicken',expirationDate:'10-03-2019'},{name:'Steak',expirationDate:'05-27-2019'},{name:'Hot-Dog',expirationDate:'03-24-2019'}];
const today = new Date();
const filterByExpiration = arr => arr.filter(({ expirationDate }) => new Date(expirationDate.replace(/-/g, "/")) > today);
console.log(filterByExpiration(menuItems));
.as-console-wrapper { max-height: 100% !important; top: auto; }
The replace is to make the date strings into valid dates - not all browsers support hyphenated dates.
You could use Date.parse(date) to get the timestamp of the passed data and filter them if the difference with the current date is negative.
Your code should be something like this:
const menuItems = [
{
name: 'Hamburger',
expirationDate: '09-24-2019'
},
{
name: 'Chicken',
expirationDate: '10-03-2019'
},
{
name: 'Hot-Dog',
expirationDate: '03-24-2019'
},
];
function filterByExpiration (items) {
let today = new Date();
let dd = today.getDate();
let mm = today.getMonth();
let yyyy = today.getFullYear();
if (dd < 10) {
dd = '0' + dd;
}
if (mm < 10) {
mm = '0' + mm;
}
today = mm + '-' + dd + '-' + yyyy;
return menuItems.filter((item) => item.expirationDate > today)
};
You are comparing two different string. Its much better to convert both date object in timestamp or any value where you can compare.
new Date(); //gives something like this Wed Jun 26 2019 02:55:59 GMT+0530
and you are trying to compare with '03-24-2019' something like this. Possible flow would be :
const menuItems = [{
name: 'Hamburger',
expirationDate: '09-24-2019'
},
{
name: 'Chicken',
expirationDate: '10-03-2019'
},
{
name: 'Hot-Dog',
expirationDate: '03-24-2019'
},
];
const today = new Date().getTime();
const filterByExpiration = menuItems.filter((items) => {
return new Date(items.expirationDate).getTime() > today;
})
console.log(filterByExpiration)
const menuItems = [
{
name: 'Hamburger',
expirationDate: '09-24-2019'
},
{
name: 'Pizza',
expirationDate: '03-11-2019'
},
{
name: 'Sushi',
expirationDate: '03-21-2019'
},
{
name: 'Chicken',
expirationDate: '10-03-2019'
},
{
name: 'Steak',
expirationDate: '05-27-2019'
},
{
name: 'Hot-Dog',
expirationDate: '03-24-2019'
},
];
const filterByExpiration = () => {
const Today = Date.now()
return menuItems.filter(function (item) {
return new Date(item.expirationDate).getTime() > Today;
});
};
filterByExpiration();
Read More About filter
For Older Browsers
var filterByExpiration = () => {
var Today = new Date();
return menuItems.filter(function (item) {
var year = Today.getFullYear();
var month = Today.getMonth()+1;
var day = Today.getDay();
var dateYearArray = item.expirationDate.split('-');
var dateYear = dateYearArray[2];
var dateMonth = dateYearArray[0];
var dateDay = dateYearArray[1];
var isYear = year > dateYear;
var isMonth = month > dateMonth;
var isDay = day > dateDay;
return !(isYear || isMonth || isDay);
});
};
filterByExpiration();

How to get dates array between two date time

I have a following date fields
{ tripScheduleStartDate: '2018-12-05T18:30:00.000Z',
tripScheduleEndDate: '2018-12-07T18:30:00.000Z',
}
How can i get datetime array from start to end, something like this
[ { date: '2018-12-05T18:30:00.000Z' }, { date: '2018-12-06T18:30:00.000Z' },{ date: '2018-12-07T18:30:00.000Z' } ]
PSEUDO-CODE
Time start = x;
Time end = y
tmpTime = x;
timeArray = [];
While (tmpTime < y) {
timeArray.Add(tmpTime)
tmpTime = tmpTime.AddDays(1);
}
You could use eachDay from date-fns.
{
tripScheduleStartDate: '2018-12-05T18:30:00.000Z',
tripScheduleEndDate: '2018-12-07T18:30:00.000Z',
}
Import: import eachDay from 'date-fns/each_day'
Usage: eachDay(tripScheduleStartDate, tripScheduleEndDate)
This may help you
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
function gettheDates(sDate, eDate) {
var dateArray = new Array();
var ctDate = sDate;
while (ctDate <= eDate) {
dateArray.push(new Date (ctDate ));
ctDate = ctDate .addDays(1);
}
return dateArray;
}

Date object doesn't exist after definition?

I'm trying to make a function that returns an array of dates in between two dates. This is my code:
Date.prototype.addDays = function(days)
{
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
function getdaterange(startdate, enddate)
{
var s = new Date(startdate);
var e = new Date(enddate);
var datearray = [s];
var done = false;
while(!done)
{
var date = datearray.pop().addDays(1);
if (date == e)
{
datearray.push(date);
done = true;
}
}
}
getdaterange("2018-09-01", "2018-09-25");
The function isn't done yet, but when I try to manipulate the date object on the line that sets the variable "date", it comes back as undefined or says that .pop() isn't a method of Date. I've tried several different configurations. (Where I change how I am manipulating the date object. For example: defining the variable and then calling the .addDays() method afterwards.)
This is just one of them. Does anybody know whats going on?
Thanks for any help in advanced.
Thanks for your help from the comments. Edited Code:
Date.prototype.addDays = function(days)
{
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
function getdaterange(startdate, enddate)
{
var s = new Date(startdate);
var e = new Date(enddate);
var datearray = [s];
var done = false;
while(!done)
{
var temp = datearray;
var date = temp.pop().addDays(1);
if (date.valueOf() == e.valueOf())
{
datearray.push(date);
done = true;
}
else
{
datearray.push(date);
}
}
return datearray;
}
console.log(getdaterange("2018-09-01", "2018-09-25"));
Rather than trying to 'extend' the Date class, you can encapsulate the desired logic in it's own class as follows
class DateUtil {
static addDays(date, days) {
return date.setDate(date.getDate() + days)
}
static getDateRange(dateStart, dateEnd) {
let date = new Date(dateStart);
let endDate = new Date(dateEnd);
let dates = [];
while (date < endDate) {
dates.push(new Date(this.addDays(date, 1)))
}
return dates;
}
}
DateUtil.getDateRange('2018-09-01', '2018-09-25')
.forEach(date => console.log(date.toString()));
What I ended up needing to do (after fixing the first problem) was set var temp equal to var datearray through a method like Array.from(). That way temp wasn't pointing to datearray directly and I always ended up with one item in the array.
Date.prototype.addDays = function(days)
{
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
function getdaterange(startdate, enddate)
{
var s = new Date(startdate);
var e = new Date(enddate);
var datearray = [s];
var done = false;
while(!done)
{
var temp = Array.from(datearray);
var date = temp.pop().addDays(1);
if (date.valueOf() == e.valueOf())
{
datearray.push(date);
done = true;
}
else
{
datearray.push(date);
}
}
return datearray;
}

How to return an array of all the dates between two selected dates using javascript

For my class assignment, I need to return an array of dates in between two selected dates on a calendar (arrival & departure).
I was given two sets of code that I can use, however I can't figure out how to link them together.
var arrival = document.getElementById('arrivalDate');
console.log(arrival.value);
var checkout = document.getElementById('departureDate');
console.log(checkout.value);
// Figure out the number of days they are check in for.
var days = checkout.value.split('-')[2] - arrival.value.split('-')[2];
console.log(days);
function dateRange(arrival, days) {
range = [];
// Starting At
return range;
}
// Returns an array of dates between the two dates
var getDates = function(startDate, endDate) {
var dates = [],
currentDate = startDate,
addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
};
while (currentDate <= endDate) {
dates.push(currentDate);
currentDate = addDays.call(currentDate, 1);
}
return dates;
};
// Usage
var dates = getDates(new Date(2013,10,22), new Date(2013,11,25));
dates.forEach(function(date) {
console.log(date);
});
Seems pretty simple when you've already been given the answer!
var arrivalDate = new Date(document.getElementById('arrivalDate').value);
var departureDate = new Date(document.getElementById('departureDate').value);
var dateRange = getDates(arrivalDate, departureDate);

Categories

Resources