Year Converter Function - javascript

i'm trying to make a function where you input a year, and the output return the centure that year is from. I got most of down, but somewhere in the logic i'm missing something and i'm not getting the correct values for when the year is, i.e. 2000 (20th century, and i get 21st)
My JS:
function centuryFromYear(year) {
if (year <= 100) {
console.log("um")
return year * 0 + 1
} else if (year > 100 && year <= 1000) {
console.log("dois")
var kek = year / 100
var lul = Math.floor(kek)
} else if (year > 1001) {
console.log("tres")
var kek = year / 100
var lul = Math.floor(kek)
return (lul + 1)
}
}

May be this:
function centuryFromYear(year) {
return Math.floor((year - 1) / 100) + 1;
}
//* tests
[100,101,250, 1000, 1001, 1999, 2000, 2001].forEach(function(y) {
console.log(y + ' year is in ' + centuryFromYear(y) + ' century');
});

Apologies for a slightly messy approach, I am sure there is possibly a more elegant approach available:
Note: negative centuries and year 0 AD do not exist on the Georgian calender
function myFunction() {
year = 2000;
b = year;
if (b % 100 > 0){
b = Math.floor((year)/100);
b = b +1 ;
}
else if (b % 100 == 0){
b = Math.floor((year)/100);
}
else if (b < 100 && b > 0){
b = (Math.floor((year)/100)+1);
}
}

Related

How to convert timestamp into days in javascript?

i get endtimestamp as api response and i want calculate days from current time stamp.i have written one function for this conversion but give me worng result.
function timeDifference(current, previous) {
var msPerMinute = 60 * 1000;
var msPerHour = msPerMinute * 60;
var msPerDay = msPerHour * 24;
var msPerMonth = msPerDay * 30;
var msPerYear = msPerDay * 365;
var elapsed = current - previous;
if (elapsed < msPerMinute) {
return Math.round(elapsed/1000) + ' seconds ago';
}
else if (elapsed < msPerHour) {
return Math.round(elapsed/msPerMinute) + ' minutes ago';
}
else if (elapsed < msPerDay ) {
return Math.round(elapsed/msPerHour ) + ' hours ago';
}
else if (elapsed < msPerMonth) {
return '' + Math.round(elapsed/msPerDay) + ' days ago';
}
else if (elapsed < msPerYear) {
return '' + Math.round(elapsed/msPerMonth) + ' months ago';
}
else {
return '' + Math.round(elapsed/msPerYear ) + ' years ago';
}
}
please suggest me right solution so i can get correct conversion
I recommend to use a library as moment.js
https://momentjs.com/docs/#/displaying/difference/
Besides easier coding you won't get problems with leap years, leap seconds etc.
function timeDifference(date) {
var seconds = Math.floor((new Date() - date) / 1000);
if(Math.round(seconds/(60*60*24*365.25)) >= 2) return Math.round(seconds/(60*60*24*365.25)) + " years ago";
else if(Math.round(seconds/(60*60*24*365.25)) >= 1) return "1 year ago";
else if(Math.round(seconds/(60*60*24*30.4)) >= 2) return Math.round(seconds/(60*60*24*30.4)) + " months ago";
else if(Math.round(seconds/(60*60*24*30.4)) >= 1) return "1 month ago";
else if(Math.round(seconds/(60*60*24*7)) >= 2) return Math.round(seconds/(60*60*24*7)) + " weeks ago";
else if(Math.round(seconds/(60*60*24*7)) >= 1) return "1 week ago";
else if(Math.round(seconds/(60*60*24)) >= 2) return Math.round(seconds/(60*60*24)) + " days ago";
else if(Math.round(seconds/(60*60*24)) >= 1) return "1 day ago";
else if(Math.round(seconds/(60*60)) >= 2) return Math.round(seconds/(60*60)) + " hours ago";
else if(Math.round(seconds/(60*60)) >= 1) return "1 hour ago";
else if(Math.round(seconds/60) >= 2) return Math.round(seconds/60) + " minutes ago";
else if(Math.round(seconds/60) >= 1) return "1 minute ago";
else if(seconds >= 2)return seconds + " seconds ago";
else return seconds + "1 second ago";
}
you can also use this plugin javascript-time-ago
i love reducing things, here is my solution.
/**
* #method msToTimeString : convert milliseconds to time string
* #param {number} ms : milliseconds to convert
*/
const msToTimeString = ms => {
const mods = [1000, 60, 60, 24, 365]; // time modulus
const names = ["millisecond", "second", "minute", "hour", "day"]; // names
return mods.reduce((acc, cur, index) => { // reduce modulus
let unit = acc.val % cur; // calc current time scale
acc.val = (acc.val - unit) / cur; // keep remaining
acc[names[index]] = unit; // assign name to result
return acc; // next
}, {val: ms});
};
let past = new Date("2020-03-17T00:00:00").getTime(), // past date
now = Date.now(); // now
let calc = msToTimeString(now - past);
console.log(calc.day, "days", calc.hour, "hours"); // also : calc.minute, calc.second, calc.millisecond
same code, savage one-liner
/**
* #method msToTimeString : convert milliseconds to time string
* #param {number} ms : milliseconds to convert
*/
const msToTimeString = ms => {
const names = ["millisecond", "second", "minute", "hour", "day"]; // names
return [1000, 60, 60, 24, 365].reduce((acc, cur, index) => ({...acc, [names[index]]: acc.val % cur, val: (acc.val - (acc.val % cur)) / cur}), {val: ms});
};
let past = new Date("2020-03-17T00:00:00").getTime(), // past date
now = Date.now(); // now
console.log(msToTimeString(now - past)); // display !

How can I calculate the number of "quarters" that have passed between 2 dates, where quarters are not simply a quarter of a year, but specific dates?

I am trying to make a "Rent Arrears Calculator" using Javascript, and one of the desired functions is to have the option of calculating rent per week, per month or per quarter.
If rent is payable quarterly, the number of quarters late will increase when the date passes a certain day. These quarter days are 25/03, 24/06, 29/09/ and 25/12 every year.
My code at the moment returns the incorrect value when the month of the input date is greater than the month of a quarter date, but its Date is less than the date of the quarter.
i.e. for a "First missed payment date" of 24/06/2014, and a date of 22/04/2015, this should return 4, but instead returns 1. It should return 4 since 4 quarter dates have been passed in this time (24/06/2014, 29/09/2014, 25/12/2014, and 25/03/2015).
Here is my code:
function getNumberPeriods() {
var years = (getNumberYears());
var days = (getNumberDays());
if ((getPeriodLength()) == "Weekly") {
return ((days - (days % 7)) / 7);
} else if ((getPeriodLength()) == "Monthly") {
var months = ((((options.untilDate).getMonth()) + 1) - (((options.dueDate).getMonth()) + 1) + (12 * years));
if (((options.untilDate).getDate()) < ((options.dueDate).getDate())) {
months--;
}
return (months + 1);
} else if ((getPeriodLength()) == "Quarterly") {
if ((options.dueDate).getMonth() == 2) {
if (((options.untilDate).getMonth() <= 5) && ((options.untilDate).getDate() < 24)) {
return (1+(years * 4));
}
else if (((options.untilDate).getMonth() <= 5) && ((options.untilDate).getDate() >= 24)) {
return (2+(years * 4));
}
else if (((options.untilDate).getMonth() <= 8) && ((options.untilDate).getDate() < 29)) {
return (2 + (years * 4));
}
else if (((options.untilDate).getMonth() <= 8) && ((options.untilDate).getDate() >= 29)) {
return (3 + (years * 4));
}
else if (((options.untilDate).getMonth() <= 11) && ((options.untilDate).getDate() < 25)) {
return (3 + (years * 4));
}
else if (((options.untilDate).getMonth() <= 11) && ((options.untilDate).getDate() >= 25)) {
return ((years * 4)+4);
}
else return (years * 4);
}
else if ((options.dueDate).getMonth() == 5) {
if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() < 25) {
return (3 + (years * 4));
}
else if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() >= 25) {
return (4+(years * 4));
}
else if ((options.untilDate).getMonth() <= 8 && (options.untilDate).getDate() < 29) {
return ((years * 4)+1);
}
else if ((options.untilDate).getMonth() <= 8 && (options.untilDate).getDate() >= 29) {
return ((years * 4)+2);
}
else if ((options.untilDate).getMonth() <= 11 && (options.untilDate).getDate() < 25) {
return (2 + (years * 4));
}
else if ((options.untilDate).getMonth() <= 11 && (options.untilDate).getDate() >= 25) {
return (3 + (years * 4));
}
else return (years * 4);
}
else if ((options.dueDate).getMonth() == 8) {
if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() < 25) {
return (2 + (years * 4));
}
if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() >= 25) {
return (3 + (years * 4));
}
else if ((options.untilDate).getMonth() <= 5 && (options.untilDate).getDate() < 24) {
return (3 + (years * 4));
}
else if ((options.untilDate).getMonth() <= 5 && (options.untilDate).getDate() >= 24) {
return (4+(years * 4));
}
else if ((options.untilDate).getMonth() <= 11 && (options.untilDate).getDate() < 25) {
return ((years * 4)+1);
}
else if ((options.untilDate).getMonth() <= 11 && (options.untilDate).getDate() >= 25) {
return ((years * 4)+2);
}
else return (years * 4);
}
else if ((options.dueDate).getMonth() == 11) {
if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() < 25) {
return ((years * 4)+1);
}
else if ((options.untilDate).getMonth() <= 2 && (options.untilDate).getDate() >= 25) {
return ((years * 4)+2);
}
else if ((options.untilDate).getMonth() <= 5 && (options.untilDate).getDate() < 24) {
return (2 + (years * 4));
}
else if ((options.untilDate).getMonth() <= 5 && (options.untilDate).getDate() >= 24) {
return (3 + (years * 4));
}
else if ((options.untilDate).getMonth() <= 8 && (options.untilDate).getDate() < 29) {
return (3 + (years * 4));
}
else if ((options.untilDate).getMonth() <= 8 && (options.untilDate).getDate() >= 29) {
return ((years * 4)+4);
}
else return (years * 4);
}
else alert("not werkin");
}
}
function getNumberDays() {
return ((((options.untilDate)) - ((options.dueDate))) / (1000 * 60 * 60 * 24));
}
function getNumberYears() {
var dueMonth = (options.dueDate).getMonth();
var dueDay = (options.dueDate).getDate();
var dueYear = (options.dueDate).getFullYear();
var untilYear = (options.untilDate).getFullYear();
var untilMonth = (options.untilDate).getMonth();
var untilDay = (options.untilDate).getDate();
var diffyears = untilYear - dueYear;
if (untilMonth < dueMonth - 1){
diffyears--;
}
if (dueMonth - 1 == untilMonth && untilDay < dueDay){
diffyears--;
}
return diffyears;
And this is a link to my JS fiddle (I'm aware that other part of the fiddle aren't working correctly yet I just haven't got to those yet).
Any help would be very greatly appreciated!
Zehra.
The following code counts the passed quarters into passed
var quarters = [{'month':3, 'day':25}, {'month':6, 'day':24},
{'month':9, 'day':29}, {'month':12, 'day':25}];
var year = options.dueDate.getFullYear();
var passed = 0; // this is the number of passed quarters
var quarterIndex = 0;
do {
// month is 0 based
var reference = new Date(
year,
quarters[quarterIndex].month - 1,
quarters[quarterIndex].day);
if( (reference >= options.dueDate) && (reference <= options.untilDate) ) {
passed ++;
}
quarterIndex++;
if(4 == quarterIndex) {
quarterIndex = 0;
year++;
}
} while(reference < options.untilDate);
In your code you are trying to cover up all of the cases there might be. It is not a very good approach for this problem (and the majority of other problems with large number of cases). Instead, try to think in a different way: you can loop through the quarter dates and see if they are in the period between dueDate and untilDate. However, you are missing the year component of the date to do that. I suggest to use the dueDate's year to construct Date objects in the beginning and then increase the year with each iteration, until year becomes greater than untilDate's year.
Here is the code listing:
} else if ((getPeriodLength()) == "Quarterly") {
// We have an array of all the quarter dates
var quarterDates = [
{
'm': 3,
'd': 25
},
{
'm': 6,
'd': 24
},
{
'm': 9,
'd': 29
},
{
'm': 12,
'd': 25
}];
// The count of missed periods
var count = 0;
// Initial year value
var year = options.dueDate.getFullYear();
// Condition on when to stop
while (year <= options.untilDate.getFullYear()) {
for(var i in quarterDates) {
// Just a precaution, because foreach in js
// loops through all properties of the object
// and there might be functions and we want to
// skip them
if (typeof(quarterDates[i]) != 'function') {
// Construct a Date object
// Note: months in js have numbers from 0 to 11
var qDate = new Date(year, quarterDates[i].m - 1, quarterDates[i].d);
// If the date is in the given period
if (qDate >= options.dueDate && qDate <= options.untilDate) {
// Increase the counter
count++;
}
}
}
// Increase the value
year++;
}
return count;
}

Convert JavaScript to C#

How to convert this JavaScript to C#?
<script>
function zeroPad(num, places) {
var zero = places - num.toString().length + 1;
return Array(+(zero > 0 && zero)).join("0") + num;
}
var accum = 0;
var pin = parseInt(form.mac.value.replace(/:/g, '').slice(-6), 16) % 12000;
var p = pin;
while (pin)
accum = (((accum + (3 * (pin % 10))) | 0) + (((pin / 10) | 0) % 10)) | 0, pin = ((pin / 100) | 0);
accum = ((10 - accum % 10) % 10);
form.pin.value = (zeroPad(p, 7) + "" + accum);
}
</script>
Please explain me this line in details?
parseInt(form.mac.value.replace(/:/g, '').slice(-6), 16) % 12000;
I believe start-to-finish code conversions are a bit out of scope of Stack Overflow. If you posted your non-working C# conversion attempt and asked where it went wrong, I'm sure you'd get a much quicker answer to your first question.
As for your second question:
parseInt(form.mac.value.replace(/:/g, '').slice(-6), 16) % 12000;
translates to:
// Gets some mac address from some object outside the code you posted
var MACAddrString = form.mac.value;
// Delete the :'s between MAC address bytes
MACAddrString = MACAddrString.replace(/:/g, '');
// Take the last 3 bytes (6 hex digit symbols)
MACAddrString = MACAddrString.slice(-6);
// Parse the hex string to a number. Second argument indicates base 16.
var MACAddrInt = parseInt(MACAddrString, 16);
// Calculate the pin
var pin = MACAddrInt % 12000;
Wrapping javascript function for access using c# instead of conversion/porting
You could look into using Jurassic for doing that.
Calling a JavaScript function from .NET
$(document).ready(function () { StartCountDown(); }); //start the countdown
function Decrement() {
currentMinutes = Math.floor(secs / 60);
currentSeconds = secs % 60;
if (currentSeconds <= 9) currentSeconds = "0" + currentSeconds;
secs--;
document.getElementById("timerText").innerHTML = "Time Remaining " + currentMinutes + ":" + currentSeconds;
if (secs !== -1) {
setTimeout('Decrement()', 1000);
}
else {
window.location.href = "default.aspx?timeout=1"
}
}
function CheckIfAllQuestionAnswerHasBeenSubmitted() {
var numItems = $('.tblOptions').length;
var flagtocheckcount = 0;
$(".tblOptions").each(function () {
var groupname = $('input[type=radio]:first', this).attr('name');
if (!$("input[name='" + groupname + "']:checked").val()) {
$(this).parents(".tableclass").addClass("border");
var tableid = $(this).closest('table [class^="tableclass"]').attr("id");
}
else {
flagtocheckcount = flagtocheckcount + 1;
}
})

NaN:NaN in firefox and IE ,CHROME works fine

My script is OK in Chrome, but in FireFox and IE the result is: NaN:NaN.
This is my script: Anyone knows whats wrong?
Output of $db[time] is : 2013-10-07 14:28:35 (Timestamp database)
<script>
var end = new Date('<?=$db[time]?>');
var _second = 1000;
var _minute = _second * 60;
var _hour = _minute * 60;
var _day = _hour * 24;
var timer;
function showRemaining() {
var now = new Date();
var distance = end - now;
if (distance < 0) {
clearInterval(timer);
document.getElementById('countdown').innerHTML = 'ITS NOW TIME!</font><BR><BR>';
return;
}
var days = Math.floor(distance / _day);
var hours = Math.floor((distance % _day) / _hour);
var minutes = Math.floor((distance % _hour) / _minute);
var seconds = Math.floor((distance % _minute) / _second);
document.getElementById('countdown').innerHTML = '<font color="orange">' + minutes + ':';
document.getElementById('countdown').innerHTML += '<font color="orange">' + seconds + ' minutes</font>';
}
timer = setInterval(showRemaining, 1000);
</script>
This is because of the value of $db[time].
You said in a comment the format of the date/time is 2013-10-07 14:28:35 which is the default DATETIME output for MySQL, when it needs to be 2013-10-07T14:28:35.
Chrome supports the 2013-10-07 14:28:35 format as a convenience however it's not in the Javascript spec, so not all other browsers do.
Try this:
<? echo str_replace(' ', 'T', $db['time']); ?>
javascript time format different from php so firefox will display NaN:NaN:NaN. you should covert time as below:
PHP date format
$yourDate = date("M d, Y H:i:s", strtotime($db['time'])));
get time like this
date = new date("<?=$yourDate?>").getTime();
You could parse the date string yourself rather than relying on a modern browsers with modern methods, something like the following should be cross-browser friendly. Countdown is in milliseconds, you can format it as you wish.
HTML
<div id="countdown"></div>
Javascript
function isGregorianLeapYear(year) {
return year % 400 === 0 || year % 100 !== 0 && year % 4 === 0;
}
function daysInGregorianMonth(year, month) {
var days;
if (month == 2) {
days = 28;
if (isGregorianLeapYear(year)) {
days += 1;
}
} else {
days = 31 - ((month - 1) % 7 % 2);
}
return days;
}
function timeStampToDate(timeStamp) {
var dateObject,
dateTime,
date,
time,
value;
if (typeof timeStamp === "string") {
dateTime = timeStamp.split(" ");
if (dateTime.length === 2) {
date = dateTime[0].split("-");
if (date.length === 3) {
value = +date[0];
if (date[0].length === 4 && value >= -9999 && value <= 9999) {
value = +date[1];
if (date[1].length === 2 && value >= 1 && value <= 12) {
date[1] = value - 1;
value = +date[2];
if (date[2].length === 2 && value >= 1 && value <= daysInGregorianMonth(+date[0], date[1])) {
time = dateTime[1].split(":");
if (time.length === 3) {
value = +time[0];
if (time[0].length === 2 && value >= 0 && value <= 23) {
value = +time[1];
if (time[1].length === 2 && value >= 0 && value <= 59) {
value = +time[2];
if (time[2].length === 2 && value >= 0 && value <= 59) {
dateObject = new Date(Date.UTC.apply(Date, date.concat(time)));
}
}
}
}
}
}
}
}
}
}
if (typeof dateObject === "undefined") {
dateObject = new Date(NaN);
}
return dateObject;
}
function emptyNode(node) {
while (node.firstChild) {
node.removeChild(node.firstChild);
}
}
var countdown = document.getElementById("countdown"),
end = timeStampToDate("2013-10-07 16:57:00"),
intervalId;
end = end.getTime() + end.getTimezoneOffset() * 60000;
function showRemaining() {
var now = new Date().getTime();
if (isNaN(end) || isNaN(now)) {
clearInterval(intervalId);
emptyNode(countdown);
countdown.appendChild(document.createTextNode("Error"));
} else if (now < end) {
emptyNode(countdown);
countdown.appendChild(document.createTextNode(end - now));
} else {
clearInterval(intervalId);
emptyNode(countdown);
countdown.appendChild(document.createTextNode("ITS NOW TIME!"));
}
}
intervalId = setInterval(showRemaining, 1000);
jsFiddle

add/subtract business days in Javascript

I need a Date.prototype.addBusDays function
that'll take an integer as the number of working days to add to the date.
However, there are two considerations: 1. Weekends, 2. Holidays (which I imagine would be a preset array to compare against. If beginning date and end date contain 3 holidays, then you push out the end date by 3)
I have come across some scripts online, one dilemma I can think of is, lets say you address all the weekends first, then you do the holidays, what if you +1 day (due to holiday), and your end date is pushed into a weekends again...<
Any ideas?
Thanks!
EDIT:
This is a part of a scheduling tool I am developing, which mean the dates will be tied to tasks which are linked together. Adding 1 day to a task, will trigger a recalculation of everything tied to it, potentially all dates in the database.
Datageek's solution helped me but I needed to augment it. This still doesn't do holidays but does do working days with the option of including Sat and/or Sun, and does support adding negative days:-
function AddWorkingDays(datStartDate, lngNumberOfWorkingDays, blnIncSat, blnIncSun) {
var intWorkingDays = 5;
var intNonWorkingDays = 2;
var intStartDay = datStartDate.getDay(); // 0=Sunday ... 6=Saturday
var intOffset;
var intModifier = 0;
if (blnIncSat) { intWorkingDays++; intNonWorkingDays--; }
if (blnIncSun) { intWorkingDays++; intNonWorkingDays--; }
var newDate = new Date(datStartDate)
if (lngNumberOfWorkingDays >= 0) {
// Moving Forward
if (!blnIncSat && blnIncSun) {
intOffset = intStartDay;
} else {
intOffset = intStartDay - 1;
}
// Special start Saturday rule for 5 day week
if (intStartDay == 6 && !blnIncSat && !blnIncSun) {
intOffset -= 6;
intModifier = 1;
}
} else {
// Moving Backward
if (blnIncSat && !blnIncSun) {
intOffset = intStartDay - 6;
} else {
intOffset = intStartDay - 5;
}
// Special start Sunday rule for 5 day week
if (intStartDay == 0 && !blnIncSat && !blnIncSun) {
intOffset++;
intModifier = 1;
}
}
// ~~ is used to achieve integer division for both positive and negative numbers
newDate.setTime(datStartDate.getTime() + (new Number((~~((lngNumberOfWorkingDays + intOffset) / intWorkingDays) * intNonWorkingDays) + lngNumberOfWorkingDays + intModifier)*86400000));
return newDate;
}
Have a look at the following implementation. Sourced from about.com
addWeekdays = function(date, dd) {
var wks = Math.floor(dd/5);
var dys = dd.mod(5);
var dy = this.getDay();
if (dy === 6 && dys > -1) {
if (dys === 0) {dys-=2; dy+=2;}
dys++; dy -= 6;
}
if (dy === 0 && dys < 1) {
if (dys === 0) {dys+=2; dy-=2;}
dys--; dy += 6;
}
if (dy + dys > 5) dys += 2;
if (dy + dys < 1) dys -= 2;
date.setDate(date.getDate()+wks*7+dys);
}
var date = new Date();
addWeekdays(date, 9);
(Updated) I've put this algorithm through its paces and it seems stable, though it does use recursion for holiday processing:
holidays = [new Date("2/13/2019"), new Date("2/19/2019")];
function addWorkdays(workdays, startDate) {
//Make adjustments if the start date is on a weekend
let dayOfWeek = startDate.getDay();
let adjustedWorkdays = Math.abs(workdays);
if (0 == dayOfWeek || 6 == dayOfWeek) {
adjustedWorkdays += (Math.abs((dayOfWeek % 5) + Math.sign(workdays)) % 2) + 1;
dayOfWeek = (dayOfWeek - 6) * -1;
}
let endDate = new Date(startDate);
endDate.setDate(endDate.getDate() + (((Math.floor(((workdays >= 0 ? dayOfWeek - 1 : 6 - dayOfWeek) + adjustedWorkdays) / 5) * 2) + adjustedWorkdays) * (workdays < 0 ? -1 : 1)));
//If we cross holidays, recompute our end date accordingly
let numHolidays = holidays.reduce(function(total, holiday) { return (holiday >= Math.min(startDate, endDate) && holiday <= Math.max(startDate, endDate)) ? total + 1 : total; }, 0);
if (numHolidays > 0) {
endDate.setDate(endDate.getDate() + Math.sign(workdays));
return addWorkdays((numHolidays - 1) * Math.sign(workdays), endDate);
} else return endDate;
}
I expanded on khellendros74's answer for a project of mine that needed to disable Sundays and mailing holidays in the datepicker and return two dates on press of a button: three business days (i.e. non-holiday and non-Sunday) after the date picked in the datepicker (a field with an id of "calendar") and six business days after the date picked in the datepicker and then put those two results into a couple of disabled input fields (handDelivered and mailed). The button press calls the function calculateDates. Here is that code:
var disabledDates = ['11/11/2015', '11/26/2015', '12/25/2015', '01/01/2016','01/18/2016', '02/15/2016','05/30/2016', '07/04/2016','09/05/2016','10/10/2016','11/11/2016','11/24/2016', '12/26/2016','01/02/2017','01/16/2017', '02/20/2017','05/29/2017', '07/04/2017','09/04/2017','10/09/2017','11/10/2017','11/23/2017', '12/25/2017','01/01/2018','01/15/2018', '02/19/2018','05/28/2018', '07/04/2018','09/03/2018','10/08/2018','11/12/2018','11/22/2018', '12/25/2018','01/01/2019','01/21/2019', '02/18/2019','05/27/2019', '07/04/2019','09/02/2019','10/14/2019','11/11/2019','11/28/2019', '12/25/2019','01/01/2020','01/20/2020', '02/17/2020','05/25/2020', '07/03/2020','09/07/2020','10/11/2020','11/26/2020','11/26/2020', '12/25/2020'];
$(function(){
$('#calendar').datepicker({
dateFormat: 'mm/dd/yy',
beforeShowDay: editDays
});
function editDays(date) {
for (var i = 0; i < disabledDates.length; i++) {
if (new Date(disabledDates[i]).toString() == date.toString() || date.getDay() == 0) {
return [false];
}
}
return [true];
}
});
function calculateDates()
{
if( !$('#calendar').val()){
alert("Please enter a date.");
document.getElementById('calendar').focus();
return false;
}
var dayThreeAdd = 0;
var daySixAdd = 0;
for (var i = 0; i < disabledDates.length; i++) {
var oneDays = AddWorkingDays($('#calendar').val(),1,true,false);
var twoDays = AddWorkingDays($('#calendar').val(),2,true,false);
var threeDays = AddWorkingDays($('#calendar').val(),3,true,false);
var fourDays = AddWorkingDays($('#calendar').val(),4,true,false);
var fiveDays = AddWorkingDays($('#calendar').val(),5,true,false);
var sixDays = AddWorkingDays($('#calendar').val(),6,true,false);
if (new Date(disabledDates[i]).toString() == oneDays.toString()) {
dayThreeAdd++;
daySixAdd++;
}
if (new Date(disabledDates[i]).toString() == twoDays.toString()) {
dayThreeAdd++;
daySixAdd++;
}
if (new Date(disabledDates[i]).toString() == threeDays.toString()) {
dayThreeAdd++;
daySixAdd++;
}
if (new Date(disabledDates[i]).toString() == fourDays.toString()) {
daySixAdd++;
}
if (new Date(disabledDates[i]).toString() == fiveDays.toString()) {
daySixAdd++;
}
if (new Date(disabledDates[i]).toString() == sixDays.toString()) {
daySixAdd++;
}
}
var threeDays = AddWorkingDays($('#calendar').val(),(3 + dayThreeAdd),true,false);
var sixDays = AddWorkingDays($('#calendar').val(),(6 + daySixAdd),true,false);
$('#handDelivered').val((threeDays.getMonth()+1) + '/' + threeDays.getDate() + '/' + (threeDays.getYear()+1900));
$('#mailed').val((sixDays.getMonth()+1) + '/' + sixDays.getDate() + '/' + (sixDays.getYear()+1900));
}
function AddWorkingDays(datStartDate, lngNumberOfWorkingDays, blnIncSat, blnIncSun) {
datStartDate = new Date(datStartDate);
var intWorkingDays = 5;
var intNonWorkingDays = 2;
var intStartDay = datStartDate.getDay(); // 0=Sunday ... 6=Saturday
var intOffset;
var intModifier = 0;
if (blnIncSat) { intWorkingDays++; intNonWorkingDays--; }
if (blnIncSun) { intWorkingDays++; intNonWorkingDays--; }
var newDate = new Date(datStartDate)
if (lngNumberOfWorkingDays >= 0) {
// Moving Forward
if (!blnIncSat && blnIncSun) {
intOffset = intStartDay;
} else {
intOffset = intStartDay - 1;
}
// Special start Saturday rule for 5 day week
if (intStartDay == 6 && !blnIncSat && !blnIncSun) {
intOffset -= 6;
intModifier = 1;
}
} else {
// Moving Backward
if (blnIncSat && !blnIncSun) {
intOffset = intStartDay - 6;
} else {
intOffset = intStartDay - 5;
}
// Special start Sunday rule for 5 day week
if (intStartDay == 0 && !blnIncSat && !blnIncSun) {
intOffset++;
intModifier = 1;
}
}
// ~~ is used to achieve integer division for both positive and negative numbers
newDate.setTime(datStartDate.getTime() + (new Number((~~((lngNumberOfWorkingDays + intOffset) / intWorkingDays) * intNonWorkingDays) + lngNumberOfWorkingDays + intModifier)*86400000));
return newDate;
}
Simple solution to solve the whole problem; you can just loop through the days to skip weekdays and holidays:
Date.prototype.holidays = {
// fill in common holidays
all: [
'0101', // Jan 01
'1225' // Dec 25
],
2016: [
// add year specific holidays
'0104' // Jan 04 2016
],
2017: [
// And so on for other years.
]
};
Date.prototype.addWorkingDays = function(days) {
while (days > 0) {
this.setDate(this.getDate() + 1);
if (!this.isHoliday()) days--;
}
return this;
};
Date.prototype.substractWorkingDays = function(days) {
while (days > 0) {
this.setDate(this.getDate() - 1);
if (!this.isHoliday()) days--;
}
return this;
};
Date.prototype.isHoliday = function() {
function zeroPad(n) {
n |= 0;
return (n < 10 ? '0' : '') + n;
}
// if weekend return true from here it self;
if (this.getDay() == 0 || this.getDay() == 6) {
return true;
}
var day = zeroPad(this.getMonth() + 1) + zeroPad(this.getDate());
// if date is present in the holiday list return true;
return !!~this.holidays.all.indexOf(day) ||
(this.holidays[this.getFullYear()] ?
!!~this.holidays[this.getFullYear()].indexOf(day) : false);
};
// Uasage
var date = new Date('2015-12-31');
date.addWorkingDays(10);
alert(date.toDateString()); // Mon Jan 18 2016
date.substractWorkingDays(10);
alert(date.toDateString()) // Thu Dec 31 2015
This only takes weekends into account and not holidays, but it's a start...
function mod(x, y) {
// https://stackoverflow.com/a/4467559/2173455
return ((x % y) + y) % y;
}
function calculateDateDiff(date, diff) {
let returnDate = new Date(date.getTime());
let daysLeftToAdd = Math.abs(diff);
let weekendDays = 0;
let weekDay = returnDate.getDay();
while(daysLeftToAdd >= 0) {
if(weekDay == 0 || weekDay == 6) {
weekendDays++;
}
else {
daysLeftToAdd--;
}
weekDay = mod(diff > 0 ? weekDay + 1 : weekDay - 1, 7);
}
returnDate.setDate(diff > 0 ?
returnDate.getDate() + diff + weekendDays :
returnDate.getDate() + diff - weekendDays
);
return returnDate;
}

Categories