I need to find number of days if i enter startDate and endDate.from the start_date to end_date i only want to retrieve weekdays i.e monday to friday along with the offcial_leave variable
for_example:
let numberOfdays;
let startDate = '2022-04-04'; //yy-mm-dd format
let endDate = '2022-04-08';
// Below variable come from db and vary according the start and endate
// eg:- 2022-12-25 will be holiday if we select start and end in december
let holidays = ['2022-04-05', '2022-04-07' ]
numberOfdays => 3
// I want to return number of days to 3
How can i achieve this in in JavaScript
thanks
First convert the startDate and endDate to javascript Date. Then, declare a variable i to store while looping through the date. Also, declare holidayIndex which stores the current index at which holiday date needs to be checked with the current date.
Inside the loop, convert the date to YYYY-MM-DD format (original format) to check if the current date (isoDate) lies between a holiday, i.e., it is not a holiday date. If the holidayIndex is at last index of array, then just check if the current date (isoDate) is not in the holidays array. If not found, then increment numberOfDays variable.
Otherwise, a holiday date is found, hence no need to increment numberOfDays. Just increment holidayIndex to be ready to match the upcoming dates for next holiday date.
Here is the solution:
let numberOfdays = 0;
const startDate = '2022-04-04'; //yy-mm-dd format
const endDate = '2022-04-08';
// Below variable come from db and vary according the start and endate
// eg:- 2022-12-25 will be holiday if we select start and end in december
const holidays = ['2022-04-05', '2022-04-07'];
let holidayIndex = 0;
const start = new Date(startDate);
const end = new Date(endDate);
let i = start;
while (i <= end) {
const isoDate = i.toISOString().split('T')[0];
if (
(holidayIndex < holidays.length - 1 && isoDate < holidays[holidayIndex] && isoDate > holidays[holidayIndex + 1]) ||
formattedDate !== holidays[holidayIndex]
) {
numberOfdays += 1;
} else {
holidayIndex += 1;
}
i.setDate(i.getDate() + 1);
}
Related
How to get date range in weekly wise from the month using javascript
Ex:
If we give month ( july) and year (2022) as input, need to get the following output.
Week1 - 03-07-2022 to 09-07-2022
Week2 - 10-07-2022 to 16-07-2022
Week3 - 17-07-2022 to 23-07-2022
Week4 - 24-07-2022 to 30-07-2022
Pls suggest your ideas.
Thank you
You will need to use a date management library like moment (deprecated) or dayjs, which will allow you to find the start and end dates of each week in a month.
Sample code:
findWeeks() {
const format = "DD-MM-YYYY";
const date = "2022-07-01";
let runningDate = dayjs(date);
// Find if first day of the month is Sunday, else go to the date that is sunday
if (dayjs(date).get('day') !== 0) {
runningDate = dayjs(date).endOf('week');
runningDate = dayjs(runningDate).add(1, 'day');
}
const weeks = [];
for (let i = 1; i < 5; i++) {
weeks.push(
`Week ${i}: ${dayjs(runningDate).format(format)} - ${dayjs(runningDate).add(6, 'day').format(format)}`
);
// move runningDate to start of week 2
runningDate = dayjs(runningDate).add(7, 'day');
}
console.log(weeks);
}
I need to display the current week of the month in the following format in react-native:
(Week 2: 05.10 - 11.10) (example of week 2 of current month)
What would be some suggestions as how to achieve this? I know that there are packages such as momentjs to build this but would like some examples of how to achieve this
any help is appreciated!
You can adapt the code below. I say "adapt" because you haven't specified when your week starts (Sunday or Monday?) or how you want to count which week within the month it is (i.e. is week #1 the first full week? The code below assumes so).
Anyway, by clicking the "Run Code Snippet" button, you'll see what it does, including some intermediate steps, which are there to illustrate where the values are coming from, and therefore what you might want to "adapt" for your needs.
//get the first day of week and last day of week, borrowed from https://stackoverflow.com/a/64529257/1024832 above
const getWeek = (date = new Date()) => {
const dayIndex = date.getDay();
const diffToLastMonday = (dayIndex !== 0) ? dayIndex - 1 : 6;
const dateOfMonday = new Date(date.setDate(date.getDate() - diffToLastMonday));
const dateOfSunday = new Date(date.setDate(dateOfMonday.getDate() + 6));
return [dateOfMonday, dateOfSunday];
}
//get week number w/in the month, adapted from https://stackoverflow.com/a/57120367/1024832
const getWeekNumber = () => {
let todaysDate = moment(moment.now());
let endOfLastMonth = moment(todaysDate).startOf('month').subtract(1, 'week');
let weekOfMonth = todaysDate.diff(endOfLastMonth, 'weeks');
return weekOfMonth;
}
//capture/log some steps along the way
const [Monday, Sunday] = getWeek();
console.log("First/Last of week as Date Objects: ", Monday, Sunday);
let Monday_formatted = moment(Monday).format("DD.MM");
let Sunday_formatted = moment(Sunday).format("DD.MM");
console.log(Monday_formatted, "-", Sunday_formatted);
console.log("Week #:", getWeekNumber());
//set the DIV content
document.getElementById("datehere").innerText = `(Week ${getWeekNumber()}): ${Monday_formatted} - ${Sunday_formatted}`;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<div id="datehere"></div>
Here's an answer as a function which returns the current week's Monday and Sunday in an array:
getWeek = (date = new Date()) => {
const dayIndex = date.getDay();
const diffToLastMonday = (dayIndex !== 0) ? dayIndex - 1 : 6;
const dateOfMonday = new Date(date.setDate(date.getDate() - diffToLastMonday));
const dateOfSunday = new Date(date.setDate(dateOfMonday.getDate() + 6));
return [dateOfMonday, dateOfSunday];
}
const [Monday, Sunday] = getWeek();
console.log(Monday, Sunday);
The response is two valid date objects. You can also pass a date object for the function to get Monday and Sunday of that date's week (e.g. getWeek(new Date(0));
But when you want to parse those dates, you should gain better knowledge of Date Object.
I have question about getting full two years from the current date. So what i did id get the current month using the new date function and used the for loop to print each of the month. But, i cant really get it to work.... I will post the code that i did below. I would be really appreciate it if anyone can tell me the logic or better way of doing it.
For example: if today current date is august it store into an array from 8 / 2020 9/ 2020 ..... 12/ 2020, 1/2021 and goes to another year to 8/2022.
var d = new Date();
var year = d.getFullYear();
var dateStr;
var currentYear;
var storeMonthYear = [];
for(var i = 1; i <= 24; i++){
dateStr = d.getMonth() + i
currentYear = year;
if(dateStr > "12"){
dateStr = dateStr - 12
// currentYear = year;
// if(currentYear){
// }
storeMonthYear[i] = dateStr + "/" + (currentYear + 1);
}
else if(dateStr > "24"){
storeMonthYear[i] = dateStr + "/" + (currentYear + 1);
}
else{
storeMonthYear[i] = dateStr + "/" + currentYear;
}
storeMonthYear[i] = d.getMonth() + i
}
export const settlementPeriod = [
{
MonthYearFirstRow1: storeMonthYear[1],
MonthYearFirstRow2: storeMonthYear[2],
MonthYearFirstRow3: storeMonthYear[3],
MonthYearFirstRow4: storeMonthYear[4],
MonthYearFirstRow5: storeMonthYear[5],
MonthYearFirstRow6: storeMonthYear[6],
MonthYearFirstRow7: storeMonthYear[7],
MonthYearFirstRow8: storeMonthYear[8],
MonthYearFirstRow9: storeMonthYear[9],
MonthYearFirstRow10: storeMonthYear[10],
MonthYearFirstRow11: storeMonthYear[11],
MonthYearFirstRow12: storeMonthYear[12],
MonthYearSecondRow13: storeMonthYear[13],
MonthYearSecondRow14: storeMonthYear[14],
MonthYearSecondRow15: storeMonthYear[15],
MonthYearSecondRow16: storeMonthYear[16],
MonthYearSecondRow17: storeMonthYear[17],
MonthYearSecondRow18: storeMonthYear[18],
MonthYearSecondRow19: storeMonthYear[19],
MonthYearSecondRow20: storeMonthYear[20],
MonthYearSecondRow21: storeMonthYear[21],
MonthYearSecondRow22: storeMonthYear[22],
MonthYearSecondRow23: storeMonthYear[23],
MonthYearSecondRow24: storeMonthYear[24]
},
];
Create the date from today, get the month and year. Iterate from 0 to 24 for now till in 24 months. If month is 12 than set month to 0 and increment the year. Push the new datestring. Increment the month for the next step.
Note: Beacsue JS counts months form 0-11 you had to add for the datestring 1 for the month and make the change of year at 12 and not 13.
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth();
let res=[];
for (let i=0; i<=24; i++) {
if (month===12) {
month = 0;
year++;
}
res.push(month+1 + '/' + year);
month++;
}
console.log(res);
Here you go, you get an array of strings like "8/2020","9/2020" etc from starting month to the last month including both( in total 25 months).
If you don't want to include last month just delete +1 from for loop condition.
let currentDate = new Date();
let settlementPeriod = [];
let numberOfMonths = 24;
for(let i=0;i<numberOfMonths+1;i++){
settlementPeriod.push(currentDate.getMonth()+1+"/"+currentDate.getFullYear()); //We add current date objects attributes to the array
currentDate = new Date(currentDate.setMonth(currentDate.getMonth()+1)); //Every time we add one month to it
}
console.log(settlementPeriod);
There are a couple of things that stick out in your code sample:
You're comparing strings and numbers (e.g. dateStr > "12"). This will lead to some weird bugs and is one of JS's most easily misused "features". Avoid it where possible.
You increment the year when you reach 12 months from now, rather than when you reach the next January
You're overwriting your strings with this line storeMonthYear[i] = d.getMonth() + i so your array is a bunch of numbers rather than date strings like you expect
Here's a code sample that I think does what you're expecting:
function next24Months() {
const today = new Date()
let year = today.getFullYear()
let monthIndex = today.getMonth()
let dates = []
while (dates.length < 24) {
dates.push(`${monthIndex + 1}/${year}`)
// increment the month, and if we're past December,
// we need to set the year forward and the month back
// to January
if (++monthIndex > 11) {
monthIndex = 0
year++
}
}
return dates
}
In general, when you're dealing with dates, you're probably better off using a library like Moment.js - dates/times are one of the most difficult programming concepts.
While #Ognjen 's answer is correct it's also a bit waseful if your date never escapes its function.
You don't need a new date every time:
function getPeriods(firstMonth, numPers){
var d = new Date(firstMonth.getTime()); // clone the start to leave firstMonth alone
d.setDate(1); // fix after #RobG
var pers = [];
var m;
for(var i = 0; i< numPers; i++){
m = d.getMonth();
pers.push(`${m+ 1}/${d.getFullYear()}`)
d.setMonth(m + 1); // JS dates automatically roll over. You can do this with d.setDate() as well and when you assign 28, 29, 31 or 32 the month and year roll over automatically
}
return pers;
}
I'm facing issue with excluding weekend dates in JavaScript.For my business requirement I want to exclude 3 days from date object Friday, Saturday and Sunday in every week.What I need here is the values of Friday should display as Monday, Saturday as Tuesday and Sunday as Wednesday. I'm able to do this.
The issue that I'm facing here is when we run the above example the a[0] value should be 21-SEP-2017 but I'm getting 20-SEP-2017 and remaining array values should not change. So please do help me out in resolving this issue
var a = ["21-SEP-2017", "22-SEP-2017", "23-SEP-2017", "24-SEP-2017", "25-SEP-2017"];
for (i = 0; i < a.length; i++) {
var startDate = a[i];
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "",
noOfDaysToAdd = 1;
var count = 0;
endDate = new Date(startDate.setDate(startDate.getDate()));
if (startDate.getDay() != 0 && startDate.getDay() != 5 && startDate.getDay() != 6) {
endDate = new Date(startDate.setDate(startDate.getDate() + i - 1));
} else {
startDate.setDate(startDate.getDate() + 3)
endDate = new Date(startDate.setDate(startDate.getDate()));
}
console.log(endDate); //You can format this date as per your requirement
}
Your code seems not finished: the variables noOfDaysToAdd and count are never used, and if they were, they would be reset in every iteration of the loop, which cannot be the purpose.
That your output shows 20 September is because you did not output a stringified version of the date, but the date object itself, and then console.log will display the date as a UTC date (notice the time part matches the timezone difference). Instead use .toString() or another way to turn the date to a localised string.
Here is how you could do it:
function toDate(s) {
return new Date(s.replace(/-/g, '/'));
}
function toStr(dt) {
var months = ["JAN","FEB","MAR","APR","MAY","JUN",
"JUL","AUG","SEP","OCT","NOV","DEC"];
return [('0'+dt.getDate()).substr(-2), months[dt.getMonth()], dt.getFullYear()]
.join('-');
}
var a = ["21-SEP-2017", "22-SEP-2017", "23-SEP-2017", "24-SEP-2017", "25-SEP-2017"],
add = 0;
var result = a.map(toDate).map(dt => {
dt.setDate(dt.getDate()+add);
var move = [0, 6, 5].indexOf(dt.getDay()) + 1;
if (move) {
add += move;
dt.setDate(dt.getDate()+move);
}
return dt;
}).map(toStr);
console.log(result);
Im building a mini calendar that just displays the current month, I have figured out how to map out the calendar, here is the code:
Code:
var month = moment(),
index = 0,
maxDay = month.daysInMonth(),
start = month.startOf("month"),
offset = (start.isoWeekday() - 1 + 7) % 7; // start from monday
var week = []; // holds the weeks
var days = []; // holds the days
do {
var dayIndex = index - offset;
if(dayIndex >= 0 && dayIndex < maxDay){
days.push({
number: dayIndex + 1,
isPast: null, // stuck here boolean
isToday: null // stuck here boolean
})
}
if(index % 7 === 6){
week.push(days);
console.log(week);
days = [];
if (dayIndex + 1 >= maxDay) {
break;
}
}
index += 1;
} while(true);
This works fine, the only issue Im having is to figure out if the day is today or its in the past?
the code is here also: https://jsfiddle.net/chghb3Lq/3/
Moment has isBefore, isAfter and isSame functions to compare moments and as the docs says:
If you want to limit the granularity to a unit other than milliseconds, pass the units as the second parameter.
There are a couple of things in your code that you can achieve in a simple way using momentjs instead of reimplementing by yourself:
To loop from the first day of the month until the last day you can use:
startOf('month') and endOf('month') as limit of the loop
add(1, 'day') to increment loop index
isBefore as loop condition
Use date() to get date of the month (1-31)
Use day() to get day of the week (0 => Sunday, ... 6 => Saturday); or weekday() to get day of the week locale aware.
Using these suggestions your code could be like the following:
var day = moment().startOf('month');
var endOfMonth = moment().endOf('month');
var week = [];
var month = [];
while( day.isBefore(endOfMonth) ){
week.push({
number: day.date(),
isPast: moment().isAfter(day, 'day'),
isToday: moment().isSame(day, 'day')
});
if( day.day() === 0 ){
month.push(week);
week = [];
}
day.add(1, 'day');
}
console.log(month);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
Use moment methods like isSame() , isBefore(), isSameOrBefore() etc.
They each allow setting comparison units like year month week day hour minute second
See Query Section of moment docs