exclude weekends in javascript date calculation - javascript

I have two sets of codes that work. Needed help combining them into one.
This code gets me the difference between two dates. works perfectly:
function test(){
var date1 = new Date(txtbox_1.value);
var date2 = new Date(txtbox_2.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;
txtbox_3.value = days + "." + hrs; }
source for the above code
The code below by #cyberfly appears to have the answer of excluding sat and sun which is what i needed. source. However, its in jquery and the above code is in JS. Therefore, needed help combining as i lacked that knowledge :(
<script type="text/javascript">
$("#startdate, #enddate").change(function() {
var d1 = $("#startdate").val();
var d2 = $("#enddate").val();
var minutes = 1000*60;
var hours = minutes*60;
var day = hours*24;
var startdate1 = getDateFromFormat(d1, "d-m-y");
var enddate1 = getDateFromFormat(d2, "d-m-y");
var days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
if(days>0)
{ $("#noofdays").val(days);}
else
{ $("#noofdays").val(0);}
});
</script>
EDIT
Made an attempt at combining the codes. here is my sample. getting object expected error.
function test(){
var date1 = new Date(startdate.value);
var date2 = new Date(enddate.value);
var diff = (date2 - date1)/1000;
var diff = Math.abs(Math.floor(diff));
var days = Math.floor(diff/(24*60*60));
var leftSec = diff - days * 24*60*60;
var hrs = Math.floor(leftSec/(60*60));
var leftSec = leftSec - hrs * 60*60;
var min = Math.floor(leftSec/(60));
var leftSec = leftSec - min * 60;
var startdate1 = getDateFromFormat(startdate, "dd/mm/yyyy hh:mm");
var enddate1 = getDateFromFormat(enddate, "dd/mm/yyyy hh:mm");
days = calcBusinessDays(new Date(startdate1),new Date(enddate1));
noofdays.value = days + "." + hrs; }
start: <input type="text" id="startdate" name="startdate" value="02/03/2015 00:00">
end: <input type="text" id="enddate" name="enddate" value="02/03/2015 00:01">
<input type="text" id="noofdays" name="noofdays" value="">

When determining the number of days between two dates, there are lots of decisions to be made about what is a day. For example, the period 1 Feb to 2 Feb is generally one day, so 1 Feb to 1 Feb is zero days.
When adding the complexity of counting only business days, things get a lot tougher. E.g. Monday 2 Feb 2015 to Friday 6 February is 4 elapsed days (Monday to Tuesday is 1, Monday to Wednesday is 2, etc.), however the expression "Monday to Friday" is generally viewed as 5 business days and the duration Mon 2 Feb to Sat 7 Feb should also be 4 business days, but Sunday to Saturday should be 5.
So here's my algorithm:
Get the total number of whole days between the two dates
Divide by 7 to get the number of whole weeks
Multiply the number of weeks by two to get the number of weekend days
Subtract the number of weekend days from the whole to get business days
If the number of total days is not an even number of weeks, add the numbe of weeks * 7 to the start date to get a temp date
While the temp date is less than the end date:
if the temp date is not a Saturday or Sunday, add one the business days
add one to the temp date
That's it.
The stepping part at the end can probably be replaced by some other algorithm, but it will never loop for more than 6 days so it's a simple and reasonably efficient solution to the issue of uneven weeks.
Some consequences of the above:
Monday to Friday is 4 business days
Any day to the same day in a different week is an even number of weeks and therefore an even mutiple of 5, e.g. Monday 2 Feb to Monday 9 Feb and Sunday 1 Feb to Sunday 8 Feb are 5 business days
Friday 6 Feb to Sunday 7 Feb is zero business days
Friday 6 Feb to Monday 9 Feb is one business day
Sunday 8 Feb to: Sunday 15 Feb, Sat 14 Feb and Fri 13 Feb are all 5 business days
Here's the code:
// Expects start date to be before end date
// start and end are Date objects
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(+start);
var e = new Date(+end);
// Set time to midday to avoid dalight saving and browser quirks
s.setHours(12,0,0,0);
e.setHours(12,0,0,0);
// Get the difference in whole days
var totalDays = Math.round((e - s) / 8.64e7);
// Get the difference in whole weeks
var wholeWeeks = totalDays / 7 | 0;
// Estimate business days as number of whole weeks * 5
var days = wholeWeeks * 5;
// If not even number of weeks, calc remaining weekend days
if (totalDays % 7) {
s.setDate(s.getDate() + wholeWeeks * 7);
while (s < e) {
s.setDate(s.getDate() + 1);
// If day isn't a Sunday or Saturday, add to business days
if (s.getDay() != 0 && s.getDay() != 6) {
++days;
}
}
}
return days;
}
I don't know how it compares to jfriend00's answer or the code you referenced, if you want the period to be inclusive, just add one if the start or end date are a business day.

Here's a simple function to calculate the number of business days between two date objects. As designed, it does not count the start day, but does count the end day so if you give it a date on a Tuesday of one week and a Tuesday of the next week, it will return 5 business days. This does not account for holidays, but does work properly across daylight savings changes.
function calcBusinessDays(start, end) {
// This makes no effort to account for holidays
// Counts end day, does not count start day
// make copies we can normalize without changing passed in objects
var start = new Date(start);
var end = new Date(end);
// initial total
var totalBusinessDays = 0;
// normalize both start and end to beginning of the day
start.setHours(0,0,0,0);
end.setHours(0,0,0,0);
var current = new Date(start);
current.setDate(current.getDate() + 1);
var day;
// loop through each day, checking
while (current <= end) {
day = current.getDay();
if (day >= 1 && day <= 5) {
++totalBusinessDays;
}
current.setDate(current.getDate() + 1);
}
return totalBusinessDays;
}
And, the jQuery + jQueryUI code for a demo:
// make both input fields into date pickers
$("#startDate, #endDate").datepicker();
// process click to calculate the difference between the two days
$("#calc").click(function(e) {
var diff = calcBusinessDays(
$("#startDate").datepicker("getDate"),
$("#endDate").datepicker("getDate")
);
$("#diff").html(diff);
});
And, here's a simple demo built with the date picker in jQueryUI: http://jsfiddle.net/jfriend00/z1txs10d/

const firstDate = new Date("December 30, 2020");
const secondDate = new Date("January 4, 2021");
const daysWithOutWeekEnd = [];
for (var currentDate = new Date(firstDate); currentDate <= secondDate; currentDate.setDate(currentDate.getDate() + 1)) {
// console.log(currentDate);
if (currentDate.getDay() != 0 && currentDate.getDay() != 6) {
daysWithOutWeekEnd.push(new Date(currentDate));
}
}
console.log(daysWithOutWeekEnd, daysWithOutWeekEnd.length);

#RobG has given an excellent algorithm to separate business days from weekends.
I think the only problem is if the starting days is a weekend, Saturday or Sunday, then the no of working days/weekends will one less.
Corrected code is below.
function dateDifference(start, end) {
// Copy date objects so don't modify originals
var s = new Date(start);
var e = new Date(end);
var addOneMoreDay = 0;
if( s.getDay() == 0 || s.getDay() == 6 ) {
addOneMoreDay = 1;
}
// Set time to midday to avoid dalight saving and browser quirks
s.setHours(12,0,0,0);
e.setHours(12,0,0,0);
// Get the difference in whole days
var totalDays = Math.round((e - s) / 8.64e7);
// Get the difference in whole weeks
var wholeWeeks = totalDays / 7 | 0;
// Estimate business days as number of whole weeks * 5
var days = wholeWeeks * 5;
// If not even number of weeks, calc remaining weekend days
if (totalDays % 7) {
s.setDate(s.getDate() + wholeWeeks * 7);
while (s < e) {
s.setDate(s.getDate() + 1);
// If day isn't a Sunday or Saturday, add to business days
if (s.getDay() != 0 && s.getDay() != 6) {
++days;
}
//s.setDate(s.getDate() + 1);
}
}
var weekEndDays = totalDays - days + addOneMoreDay;
return weekEndDays;
}
JSFiddle link is https://jsfiddle.net/ykxj4k09/2/

First Get the Number of Days in a month
totalDays(month, year) {
return new Date(year, month, 0).getDate();
}
Then Get No Of Working Days In A Month By removing Saturday and Sunday
totalWorkdays() {
var d = new Date(); // to know present date
var m = d.getMonth() + 1; // to know present month
var y = d.getFullYear(); // to knoow present year
var td = this.totalDays(m, y);// to get no of days in a month
for (var i = 1; i <= td; i++) {
var s = new Date(y, m - 1, i);
if (s.getDay() != 0 && s.getDay() != 6) {
this.workDays.push(s.getDate());// working days
}else {
this.totalWeekDays.push(s.getDate());//week days
}
}
this.totalWorkingDays = this.workDays.length;
}

I thought the above code snippets others shared are lengthy.
I am sharing a concise snippet that gives date after considering the total number of days specified. we can also customize dates other than Saturdays and Sundays.
function getBusinessDays(dateObj, days) {
for (var i = 0; i < days; i++) {
if (days > 0) {
switch (dateObj.getDay()) {
// 6 being Saturday and 0 being Sunday.
case 6, 0:
dateObj.setDate(dateObj.getDate() + 2)
break;
//5 = Friday.
case 5:
dateObj.setDate(dateObj.getDate() + 3)
break;
//handle Monday, Tuesday, Wednesday and Thursday!
default:
dateObj.setDate(dateObj.getDate() + 1)
//console.log(dateObj)
break;
}
}
}
return dateObj;
}
console.log(getBusinessDays(new Date(), 11))
//Mon Dec 20 2021 18:56:01 GMT+0530 (India Standard Time)

Related

Day of Year does not update in JavaScript?

I have JavaScript Code that calculates the day of the year (for example, January 1 would be 1 and October 30 would be 304):
var now = new Date();
//leap year rules:
// The year must be evenly divisible by 4;
// If the year can also be evenly divided by 100, it is not a leap year
// Unless the year is also evenly divisible by 400. Then it is a leap year.
if(now.getUTCFullYear() % 4 == 0){
//if the year is a leap year:
if(now.getUTCFullYear() % 100 != 0){
var day = Math.ceil((now - new Date(now.getFullYear(),0,1)) / 86400000);
document.getElementById('dayOfYear').innerHTML = day;
}
else if(now.getUTCFullYear() % 100 == 0 && now.getUTCFullYear() % 400 == 0){
var day = Math.ceil((now - new Date(now.getFullYear(),0,1)) / 86400000);
document.getElementById('dayOfYear').innerHTML = day;
}
else{
var day = Math.ceil((now - new Date(now.getFullYear(),0, 0)) / 86400000);
document.getElementById('dayOfYear').innerHTML = day;
}
}
else{
//if the year is NOT a leap year
var day = Math.ceil((now - new Date(now.getFullYear(),0, 0)) / 86400000);
document.getElementById('dayOfYear').innerHTML = day;
}
The code gets refreshed every second, since it is a clock app. However, when the clock hits 00:00:00 on the next day the Day of the Year does not update until hours later. What might be causing this?
Thanks!
You are creating a Date using local values, but counting UTC days so it ticks over at UTC midnight, not local midnight. Also, the algorithm is way too complex. Just use UTC for everything, e.g.
function getDayOfYear(d = new Date()) {
// Start of year
let yearStart = Date.UTC(d.getFullYear(), 0, 1);
// Get difference to now / ms in one day
return Math.floor(((Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()) - yearStart)) / 8.64e7) + 1;
}
[new Date(2020,0,1), // 1 Jan 2020
new Date(), // today
new Date(2020,11,31) // 31 Dec 2020
].forEach(d => console.log(d.toDateString() + ' is day ' + getDayOfYear(d)));
PS (Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()) could also be (+d + d.getTimezoneOffset() * 6e4), which is a little shorter but maybe less readable.
To have it tick over at UTC midnight:
function getUTCDayOfYear(d = new Date()) {
// Start of year
let yearStart = Date.UTC(d.getUTCFullYear(), 0, 1);
// Get difference to now / ms in one day
return Math.floor(((Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()) - yearStart)) / 8.64e7) + 1;
}
[new Date(Date.UTC(2020,0,1)), // 1 Jan 2020 UTC
new Date(Date.UTC(2020,11,31)) // 31 Dec 2020 UTC
].forEach(d => console.log(d.toString() + ' is on UTC day ' + getUTCDayOfYear(d)));

How to calculate days between two date excluding weekends in angularjs? [duplicate]

This question already has answers here:
Find day difference between two dates (excluding weekend days)
(13 answers)
Closed 3 years ago.
In my application i have two date picker as start date and end date. when user choose start and end date the system will show the days between two dates but excluding the saturday and sunday. How to calculate it by using angularjs?
Does something like this work:
var startDate = new Date("01-10-2020");
var endDate = new Date("01-20-2020");
var nextDay = new Date(startDate);
var cnt = 0;
do {
/*if (nextDay.getDay() >= 1 && nextDay.getDay() <= 5) {
cnt = cnt + 1;
}*/
cnt += (nextDay.getDay() >= 1 && nextDay.getDay() <= 5) ? 1 : 0;
nextDay.setDate(nextDay.getDate() + 1);
} while (nextDay <= endDate);
console.log("Number of week days between " + startDate + " and " + endDate + " = " + cnt);
Here is the fiddler.
You don't want to do an expensive loop over every day to see whether it is Saturday or Sunday. The logic should be as follows:
Work in UTC so we don't need to worry about time zone
Calculate total number of calendar weeks. In a single calendar week, there are guaranteed to be 5 weekdays (not weekends == SAT || SUN)
Calculate the remainder of days. This will be added to the calculation later.
Determine the "finalAdjustment" by seeing if the remainder falls on weekend days.
The number of weekdays is (5 * numWeeks) + remainderDays + finalAdjust
(function() {
"use strict";
var SUN = 0;
var MON = 1;
var TUE = 2;
var WED = 3;
var THU = 4;
var FRI = 5;
var SAT = 6;
function isWeekendDay(day) {
return day === SAT || day === SUN;
}
function numberWeekDays(start, end) {
var numCalendarDays = (end - start) / 1000 / 60 / 60 / 24;
var numWeeks = Math.floor(numCalendarDays / 7);
// Potential days to add on to the number of full calendar
// weeks. This will be adjusted by "finalAdjust"
var remainderDays = numCalendarDays % 7;
// Adjustments for start and end dates being on a weekend
// ----------------------------
// Start at one because the same day should count as 1
// but number of days between same day is 0 based on
// arithmetic above.
// Change this to 0 if you don't want end date inclusive...
var finalAdjust = 1;
var startDay = start.getUTCDay();
var endDay = end.getUTCDay();
// On a weekend, so adjust by subtracting 1
if (isWeekendDay(startDay)) {
finalAdjust--;
}
// On a weekend, so adjust by subtracting 1
if (isWeekendDay(endDay)) {
finalAdjust--;
}
// This accounts for subtracting an extra weekend when starting
// at the beginning of a weekend (e.g. Saturday into Monday)
// The end day cannot also be on a weekend based on week modular division (mod 7)
if (startDay === SAT && remainderDays > 2) {
finalAdjust--;
}
// ---------------------------
// For every full calendar week there are 5 week days
// Use that number with the remainderDays and finalAdjust above
// to arrive at the answer.
var numWeekDays = (5 * numWeeks) + remainderDays + finalAdjust;
return numWeekDays;
}
// Test cases
// Assume that the start and end dates are inclusive
// 2020-01-01 to 2020-01-01 is one day
// 2020-01-01 to 2020-01-02 is two days
// ----------------------
// A Wednesdday
var start = new Date("2020-01-08");
// A Saturday
var end = new Date("2020-02-01");
// Expected answer: 18
console.log(numberWeekDays(start, end));
// A Saturday
start = new Date("2020-01-05");
// A Monday
end = new Date("2020-01-31");
// Expected answer: 20
console.log(numberWeekDays(start, end));
// Weekday to weekday Tuesday to
start = new Date("2020-01-07");
end = new Date("2020-01-16");
// Expected: 8
console.log(numberWeekDays(start, end));
// Same week: Mon-Wed
start = new Date("2020-01-06");
end = new Date("2020-01-08");
// Expected answer: 3
console.log(numberWeekDays(start, end));
// Same day
start = new Date("2020-01-08");
end = new Date("2020-01-08");
// Expect: 1
console.log(numberWeekDays(start, end));
// Weekend only
start = new Date("2020-01-04");
end = new Date("2020-01-05");
// Expect: 0;
console.log(numberWeekDays(start, end));
// ------------------
}());
As others have stated, a date library like moment is useful here because it gives you a lot of utility functions for working with dates and durations.

How to calculate and check for a bi-weekly date

I really need your help,
Let's say my demarcation start date is: December 19, 2016 as defined by the variable x
How can I write a JavaScript function, such that it will check the present date against x and the present date against what the recurrence date will be (14) days from x as defined by the variable y.
var y = recurrence is every 14 days, thereafter from the date (x) with no end date specified (unlimited)
Ex.
function() {
if (present date == x) { alert(true) }
if (present date == y) { alert(true) }
}
You could get the number of days difference between your start date and the current date then check if that number is a multiple of 14.
function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return Math.floor((treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay);
}
var demarcationdate = new Date("2016-12-19"),
today = new Date(),
days = daysBetween(demarcationdate,today),
daystill = 14 - days%14,
rec = days%14==0,
d = new Date();
d.setDate(today.getDate() + daystill);
var nextDate = (d.getDate() + "/" + (d.getMonth() + 1) + "/" + d.getFullYear());
console.log("Days diff = "+days+". Recurs today = "+rec+". Next in "+daystill+" days ("+nextDate.toString()+").");
jsFiddle
If Date.now() == 1482181410856, 14 days from now will be 1482181410856 + (14 * 24 * 60 * 60 * 1000) == 1483391010856.
let y = new Date(Date.now() + (14 * 24 * 60 * 60 * 1000));
console.log(y.toUTCString()); // "Mon, 02 Jan 2017 21:03:30 GMT"
Assuming you really want to compare precise dates, i.e. to the milliseconds, then:
var present_date = new Date();
if(present_date.getTime() === x.getTime()) alert("Today is the same date as x");
else {
var y = new Date(x.getTime());
y.setDate(y.getDate() + 14); // add 14 days
if(present_date.getTime() === y.getTime()) alert("Today is the same date as y");
}
But most of the time we want to compare dates as full days, not milliseconds, so you'd have to compare ranges instead (from midnight to 11:59PM)... In that case, I recommend using a library to make your life easier - like moment.js for instance...
Hope this helps!
This is probably a duplicate of Add +1 to current date.
If you have a start date, say 20 December, 2016, you can calculate 14 days after that by simply adding 14 days to the date. You can then check if today's date is either of those dates, e.g.
// Create a Date for 20 December, 2016 with time 00:00:00
var startDate = new Date(2016,11,20);
// Create a Date for the start + 14 days with time 00:00:00
var startPlus14 = new Date(startDate);
startPlus14.setDate(startPlus14.getDate() + 14);
// Get today and set the time to 00:00:00.000
var today = new Date();
today.setHours(0,0,0,0);
if (+today == +startDate) {
console.log('Today is the start date');
} else if (+today == +startPlus14) {
console.log('Today is 14 days after the start date');
} else {
console.log('Today is neither the start nor 14 days after the start');
}

Add Working Days to a Date Using JavaScript

How can I use JavaScript to add working days (i.e. Mon - Friday) automatically adding weekends where necessary?
So if I were to add 5 working days to today (Tue. 22nd Nov. 2016) the result should be "Tue. 29th Nov. 2016" and not "Sun. 27th Nov. 2016".
It is possible to use Date's setDate function (in combination with getDate) to add days onto a date i.e. -
var myDate = new Date(); // Tue 22/11/2016
myDate.setDate(myDate.getDate() + 3); // Fri 25/11/2016
So once you've calculated the number of weekend days within the workdays period you can add that and the required number of workdays to the start date to get the final date.
This function should work though obviously this will not take account of national holidays -
function addWorkDays(startDate, days) {
if(isNaN(days)) {
console.log("Value provided for \"days\" was not a number");
return
}
if(!(startDate instanceof Date)) {
console.log("Value provided for \"startDate\" was not a Date object");
return
}
// Get the day of the week as a number (0 = Sunday, 1 = Monday, .... 6 = Saturday)
var dow = startDate.getDay();
var daysToAdd = parseInt(days);
// If the current day is Sunday add one day
if (dow == 0)
daysToAdd++;
// If the start date plus the additional days falls on or after the closest Saturday calculate weekends
if (dow + daysToAdd >= 6) {
//Subtract days in current working week from work days
var remainingWorkDays = daysToAdd - (5 - dow);
//Add current working week's weekend
daysToAdd += 2;
if (remainingWorkDays > 5) {
//Add two days for each working week by calculating how many weeks are included
daysToAdd += 2 * Math.floor(remainingWorkDays / 5);
//Exclude final weekend if remainingWorkDays resolves to an exact number of weeks
if (remainingWorkDays % 5 == 0)
daysToAdd -= 2;
}
}
startDate.setDate(startDate.getDate() + daysToAdd);
return startDate;
}
//And use it like so (months are zero based)
var today = new Date(2016, 10, 22);
today = addWorkDays(today, 5); // Tue Nov 29 2016 00:00:00 GMT+0000 (GMT Standard Time)
It could also be added to the Date prototype -
Date.prototype.addWorkDays = function (days) {
if(isNaN(days)) {
console.log("Value provided for \"days\" was not a number");
return
}
// Get the day of the week as a number (0 = Sunday, 1 = Monday, .... 6 = Saturday)
var dow = this.getDay();
var daysToAdd = parseInt(days);
// If the current day is Sunday add one day
if (dow == 0) {
daysToAdd++;
}
// If the start date plus the additional days falls on or after the closest Saturday calculate weekends
if (dow + daysToAdd >= 6) {
//Subtract days in current working week from work days
var remainingWorkDays = daysToAdd - (5 - dow);
//Add current working week's weekend
daysToAdd += 2;
if (remainingWorkDays > 5) {
//Add two days for each working week by calculating how many weeks are included
daysToAdd += 2 * Math.floor(remainingWorkDays / 5);
//Exclude final weekend if the remainingWorkDays resolves to an exact number of weeks
if (remainingWorkDays % 5 == 0)
daysToAdd -= 2;
}
}
this.setDate(this.getDate() + daysToAdd);
};
//And use it like so (months are zero based)
var today = new Date(2016, 10, 22)
today.addWorkDays(5); // Tue Nov 29 2016 00:00:00 GMT+0000 (GMT Standard Time)
If it's for adding a few days, not thousands of days, then this is easier and more readable:
const currentDate = new Date('2021-11-18');
console.log(currentDate.toString()); // "Thu Nov 18 2021 00:00:00 GMT+0000"
const numToAdd = 5;
for (let i = 1; i <= numToAdd; i++) {
currentDate.setDate(currentDate.getDate() + 1);
if (currentDate.getDay() === 6) {
currentDate.setDate(currentDate.getDate() + 2);
}
else if (currentDate.getDay() === 0) {
currentDate.setDate(currentDate.getDate() + 1);
}
}
console.log(currentDate.toString()); // "Thu Nov 25 2021 00:00:00 GMT+0000"
I think you can use moment-business-days.
Example:
// 22-11-2016 is Tuesday, DD-MM-YYYY is the format
moment('22-11-2016', 'DD-MM-YYYY').businessAdd(5)._d // Tue Nov 29 2016 00:00:00 GMT-0600 (CST)
const date = new Date('2000-02-02')
const daysToAdd = mapToWorkdays(date, 37)
date.setUTCDate(date.getUTCDate() + daysToAdd)
console.log( date.toISOString().split('T')[0] )
// prints 2000-03-24
/**
* #param {Date} date starting date
* #param {number} add number of workdays to add
* #return {number} total number of days to add to reach correct date
*/
function mapToWorkdays(date, add) {
const wd = weekday(date)
let r = Math.trunc(add / 5) * 2
const rem = add % 5
if (wd > 4) r += (6-wd)
else if (wd+rem > 4) r += 2
return add + r
}
/**
* #param {Date} date
* #return {number} day of the week in range of 0..6 (monday..sunday)
*/
function weekday(date) { return (date.getUTCDay()+ 6) % 7 }
Updated above script to also subtract workdays if negative days are given...
function addWorkDays(startDate, days) {
var isAddingDays = (days > 0);
var isDaysToAddMoreThanWeek = (days > 5 || days < -5);
if (isNaN(days)) {
console.log("Value provided for \"days\" was not a number");
return
}
if (!(startDate instanceof Date)) {
console.log("Value provided for \"startDate\" was not a Date object");
return
}
var dow = startDate.getDay();
var daysToAdd = parseInt(days);
if ((dow === 0 && isAddingDays) || (dow === 6 && !isAddingDays)) {
daysToAdd = daysToAdd + (1 * (isAddingDays ? 1 : -1));
} else if ((dow === 6 && isAddingDays) || (dow === 0 && !isAddingDays)) {
daysToAdd = daysToAdd + (2 * (isAddingDays ? 1 : -1));
}
if (isDaysToAddMoreThanWeek) {
daysToAdd = daysToAdd + (2 * (Math.floor(days / 5)));
if (days % 5 != 0)
daysToAdd = daysToAdd + (2 * (isAddingDays ? -1 : 1));
}
startDate.setDate(startDate.getDate() + daysToAdd);
var newDate = moment(startDate).format('MM/DD/YYYY');
return newDate;
}
This is my simplyest final solution for me:
function addWorkDays(startDate, daysToAdd) {
let dw=startDate.getDay(); //* see note
startDate.setDate(startDate.getDate()-((dw==6)?1:(dw==0)?2:0)); //*
var avance = 2 * Math.floor(daysToAdd / 5); //add 2 days for each 5 workdays
var exceso = (daysToAdd % 5) + startDate.getDay() ;
if (exceso>=6) avance +=2 ;
startDate.setDate(startDate.getDate() + daysToAdd + avance);
return startDate;
}
// If used only with business day dates, the first two lines are not required

JavaScript Date.getWeek()? [duplicate]

This question already has answers here:
Get week of year in JavaScript like in PHP
(23 answers)
Closed 5 years ago.
I'm looking for a tested solid solution for getting current week of the year for specified date. All I can find are the ones that doesn't take in account leap years or just plain wrong. Does anyone have this type of stuff?
Or even better a function that says how many weeks does month occupy. It is usually 5, but can be 4 (feb) or 6 (1st is sunday and month has 30-31 days in it)
=================
UPDATE:
Still not sure about getting week #, but since I figured out it won't solve my problem with calculating how many weeks month occupy, I abandoned it.
Here's a function to find out how many weeks exactly month occupy on the calendar:
getWeeksNum: function(year, month) {
var daysNum = 32 - new Date(year, month, 32).getDate(),
fDayO = new Date(year, month, 1).getDay(),
fDay = fDayO ? (fDayO - 1) : 6,
weeksNum = Math.ceil((daysNum + fDay) / 7);
return weeksNum;
}
/**
* Returns the week number for this date. dowOffset is the day of week the week
* "starts" on for your locale - it can be from 0 to 6. If dowOffset is 1 (Monday),
* the week returned is the ISO 8601 week number.
* #param int dowOffset
* #return int
*/
Date.prototype.getWeek = function (dowOffset) {
/*getWeek() was developed by Nick Baicoianu at MeanFreePath: http://www.meanfreepath.com */
dowOffset = typeof(dowOffset) == 'number' ? dowOffset : 0; //default dowOffset to zero
var newYear = new Date(this.getFullYear(),0,1);
var day = newYear.getDay() - dowOffset; //the day of week the year begins on
day = (day >= 0 ? day : day + 7);
var daynum = Math.floor((this.getTime() - newYear.getTime() -
(this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000) + 1;
var weeknum;
//if the year starts before the middle of a week
if(day < 4) {
weeknum = Math.floor((daynum+day-1)/7) + 1;
if(weeknum > 52) {
nYear = new Date(this.getFullYear() + 1,0,1);
nday = nYear.getDay() - dowOffset;
nday = nday >= 0 ? nday : nday + 7;
/*if the next year starts before the middle of
the week, it is week #1 of that year*/
weeknum = nday < 4 ? 1 : 53;
}
}
else {
weeknum = Math.floor((daynum+day-1)/7);
}
return weeknum;
};
Usage:
var mydate = new Date(2011,2,3); // month number starts from 0
// or like this
var mydate = new Date('March 3, 2011');
alert(mydate.getWeek());
Source
For those looking for a more simple approach;
Date.prototype.getWeek = function() {
var onejan = new Date(this.getFullYear(),0,1);
var today = new Date(this.getFullYear(),this.getMonth(),this.getDate());
var dayOfYear = ((today - onejan + 86400000)/86400000);
return Math.ceil(dayOfYear/7)
};
Use with:
var today = new Date();
var currentWeekNumber = today.getWeek();
console.log(currentWeekNumber);
Consider using my implementation of "Date.prototype.getWeek", think is more accurate than the others i have seen here :)
Date.prototype.getWeek = function(){
// We have to compare against the first monday of the year not the 01/01
// 60*60*24*1000 = 86400000
// 'onejan_next_monday_time' reffers to the miliseconds of the next monday after 01/01
var day_miliseconds = 86400000,
onejan = new Date(this.getFullYear(),0,1,0,0,0),
onejan_day = (onejan.getDay()==0) ? 7 : onejan.getDay(),
days_for_next_monday = (8-onejan_day),
onejan_next_monday_time = onejan.getTime() + (days_for_next_monday * day_miliseconds),
// If one jan is not a monday, get the first monday of the year
first_monday_year_time = (onejan_day>1) ? onejan_next_monday_time : onejan.getTime(),
this_date = new Date(this.getFullYear(), this.getMonth(),this.getDate(),0,0,0),// This at 00:00:00
this_time = this_date.getTime(),
days_from_first_monday = Math.round(((this_time - first_monday_year_time) / day_miliseconds));
var first_monday_year = new Date(first_monday_year_time);
// We add 1 to "days_from_first_monday" because if "days_from_first_monday" is *7,
// then 7/7 = 1, and as we are 7 days from first monday,
// we should be in week number 2 instead of week number 1 (7/7=1)
// We consider week number as 52 when "days_from_first_monday" is lower than 0,
// that means the actual week started before the first monday so that means we are on the firsts
// days of the year (ex: we are on Friday 01/01, then "days_from_first_monday"=-3,
// so friday 01/01 is part of week number 52 from past year)
// "days_from_first_monday<=364" because (364+1)/7 == 52, if we are on day 365, then (365+1)/7 >= 52 (Math.ceil(366/7)=53) and thats wrong
return (days_from_first_monday>=0 && days_from_first_monday<364) ? Math.ceil((days_from_first_monday+1)/7) : 52;
}
You can check my public repo here https://bitbucket.org/agustinhaller/date.getweek (Tests included)
Get week number
Date.prototype.getWeek = function() {
var dt = new Date(this.getFullYear(),0,1);
return Math.ceil((((this - dt) / 86400000) + dt.getDay()+1)/7);
};
var myDate = new Date(2013, 3, 25); // 2013, 25 April
console.log(myDate.getWeek());
I know this is an old question, but maybe it helps:
http://weeknumber.net/how-to/javascript
// This script is released to the public domain and may be used, modified and
// distributed without restrictions. Attribution not necessary but appreciated.
// Source: https://weeknumber.net/how-to/javascript
// Returns the ISO week of the date.
Date.prototype.getWeek = function() {
var date = new Date(this.getTime());
date.setHours(0, 0, 0, 0);
// Thursday in current week decides the year.
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
// January 4 is always in week 1.
var week1 = new Date(date.getFullYear(), 0, 4);
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000
- 3 + (week1.getDay() + 6) % 7) / 7);
}
// Returns the four-digit year corresponding to the ISO week of the date.
Date.prototype.getWeekYear = function() {
var date = new Date(this.getTime());
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
return date.getFullYear();
}
/*get the week number by following the norms of ISO 8601*/
function getWeek(dt){
var calc=function(o){
if(o.dtmin.getDay()!=1){
if(o.dtmin.getDay()<=4 && o.dtmin.getDay()!=0)o.w+=1;
o.dtmin.setDate((o.dtmin.getDay()==0)? 2 : 1+(7-o.dtmin.getDay())+1);
}
o.w+=Math.ceil((((o.dtmax.getTime()-o.dtmin.getTime())/(24*60*60*1000))+1)/7);
},getNbDaysInAMonth=function(year,month){
var nbdays=31;
for(var i=0;i<=3;i++){
nbdays=nbdays-i;
if((dtInst=new Date(year,month-1,nbdays)) && dtInst.getDate()==nbdays && (dtInst.getMonth()+1)==month && dtInst.getFullYear()==year)
break;
}
return nbdays;
};
if(dt.getMonth()+1==1 && dt.getDate()>=1 && dt.getDate()<=3 && (dt.getDay()>=5 || dt.getDay()==0)){
var pyData={"dtmin":new Date(dt.getFullYear()-1,0,1,0,0,0,0),"dtmax":new Date(dt.getFullYear()-1,11,getNbDaysInAMonth(dt.getFullYear()-1,12),0,0,0,0),"w":0};
calc(pyData);
return pyData.w;
}else{
var ayData={"dtmin":new Date(dt.getFullYear(),0,1,0,0,0,0),"dtmax":new Date(dt.getFullYear(),dt.getMonth(),dt.getDate(),0,0,0,0),"w":0},
nd12m=getNbDaysInAMonth(dt.getFullYear(),12);
if(dt.getMonth()==12 && dt.getDay()!=0 && dt.getDay()<=3 && nd12m-dt.getDate()<=3-dt.getDay())ayData.w=1;else calc(ayData);
return ayData.w;
}
}
alert(getWeek(new Date(2017,01-1,01)));

Categories