Why my code don't compare correctly dates? - javascript

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

Related

JavaScript weekday list get

I need to create a JavaScript function for the below requirements. I need to get every week day date list. If you know nodeJs package tell me that. Thank you for your attention.
Example -
2022-01-03
2022-01-04
2022-01-05
2022-01-06
2022-01-07
2022-01-10
2022-01-11
2022-01-12
2022-01-13
2022-01-14
..........
..........
until year-end
like this pattern (only Monday to Friday)
function getWeekDaysForYear(year) {
const isLeap = year % 4 === 0;
const numberOfDays = isLeap ? 366 : 365;
let currentDate = new Date(Date.UTC(year, 0, 0, 0, 0, 0, 0));
const weekDays = [];
for(let i = 1; i <= numberOfDays; i++) {
currentDate = new Date(currentDate.getTime() + 24 * 3600 * 1000);
if (currentDate.getDay() === 0 || currentDate.getDay() === 6) {
continue;
}
weekDays.push(currentDate.toISOString().split('T')[0]);
}
return weekDays;
}
console.log(getWeekDaysForYear(2022));
This is a simple function which returns all the weekdays for the specified year in an array.
JavaScript's Date object overflows, so you can use:
for (i=1;i<366;i++) {
if (i%7==1 || i%7==2) continue;
const d = new Date(2022, 0, i);
document.write(d.toDateString(),'<br>');
}
You will need to watch for leap years, and recalculate which days are the weekend every year.
Something like this
const endDate = new Date(2022,1,2);
const date = new Date(); //today
while (endDate > date) {
const weekDay = date.getDay();
if (weekDay != 6 && weekDay != 0) {
let year = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(date);
let month = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(date);
let day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(date);
console.log(`${year}-${month}-${day}`);
}
date.setDate(date.getDate() + 1);
}
Since we're play code golf…
function getWeekDays(year) {
// Start on 1 Jan of given year
let d = new Date(Date.UTC(year, 0));
let result = [];
do {
// Only push dates that aren't Sat (6) or Sun (0)
d.getDay() % 6 ? result.push(d.toLocaleDateString('en-CA')) : null;
// Increment date
d.setDate(d.getDate() + 1);
// Until get to 1 Jan again
} while (d.getMonth() + d.getDate() > 1)
return result;
}
console.log(getWeekDays(new Date().getFullYear()))
function getWeekDaysForDateRange(start, end) {
const [startYear, startMonth, startDate] = start.split("-");
const [endYear, endMonth, endDate] = end.split("-");
let beginDate = new Date(Date.UTC(startYear, startMonth - 1, startDate - 1, 0, 0, 0, 0));
let closeDate = new Date(Date.UTC(endYear, endMonth - 1, endDate, 0, 0, 0, 0));
const weekDays = [];
while(beginDate.getTime() !== closeDate.getTime()) {
beginDate = new Date(beginDate.getTime() + 24 * 3600 * 1000);
if (beginDate.getDay() === 0 || beginDate.getDay() === 6) {
continue;
}
weekDays.push(beginDate.toISOString().split('T')[0]);
}
return weekDays;
}
console.log(getWeekDaysForDateRange('2022-01-01', '2022-01-10'));
Something like this would work for date range as you want!

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

Remove specific dates from array

I got an array, which contains dates (formatted as dates, not strings) within a specified range:
var dates = 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;
};
var startDate = new Date("2019-04-01");
var endDate = new Date("2019-04-26");
var dates = dates(startDate, endDate);
Then I filtered out the weekends like this:
var workingDays = dates.filter(function(e, index){
return (e.getDay() != 0 && e.getDay() != 6);
});
That worked perfectly so far, but my problem is that I need to filter out holidays aswell. I tried to use the same filter function as for the weekends, like this:
var holidays = [new Date("2019-04-19"), new Date("2019-04-22")];
var workingDays = dates.filter(function(e, index){
return (e.getDay() != 0 && e.getDay() != 6 && e != holidays);
});
That didn't work tho and just returned the same array as before.
Does anyone know how I can achieve this and just filter out the specified dates in the variable?
var holidays = [new Date("2019-04-19").toString(), new Date("2019-04-22").toString()];
var dates = [new Date("2019-04-19"), new Date("2019-04-22"), new Date("2019-01-21")];
var workingDays = dates.filter(function(e, index){
return (e.getDay() != 0 && e.getDay() != 6 && holidays.indexOf(e.toString()) === -1);
});
console.log(workingDays)
Since dates are objects we need some unique property we can check them on. In this case you could try the following. But I am sure there are some more optimized and elegant solutions
Since we cannot compare two Date objects, we can compare instead their ms timestamp counterparts like:
!holidays.some(d => +d === +e)
where +d and +e is a shorthand for new Date().getTime()
Example:
var dates = 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;
};
var startDate = new Date("2019-04-01");
var endDate = new Date("2019-04-26");
var dates = dates(startDate, endDate);
var holidays = [new Date("2019-04-19"), new Date("2019-04-22")];
var workingDays = dates.filter(function(e, index){
return (e.getDay() != 0 && e.getDay() != 6 && !holidays.some(d => +d === +e));
});
console.log(workingDays)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
Change e != holidays to !holidays.some( x => +x=== +e )
Explanation: +x is shortcut for call x.getTime() for compare dates timestamp.
var dates = 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;
};
var startDate = new Date("2019-04-01");
var endDate = new Date("2019-04-26");
var dates = dates(startDate, endDate);
var holidays = [new Date("2019-04-19"), new Date("2019-04-22")];
var workingDays = dates.filter(function(e, index){
return (e.getDay() != 0 && e.getDay() != 6 && !holidays.some(x=>+x===+e));
});
console.log(workingDays);

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

Generate date range given date from and to

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>

Categories

Resources