Counting weekday cycles in JavaScript - javascript

My school runs on a 7 day cycle, so if today (2016/02/26) was day 1, tomorrow would be day 0, Monday would be day 2, and the next day 1 would be 2016/03/08. I know it's very strange, but I'm trying to find a way to use the Date object in JavaScript and add on one cycle, that is 7 days, not including weekends.
I would like to emphasize that weekends DO NOT COUNT towards day counting. I'm trying to find a way to omit weekends and easily find the next day 1 or day 5 or whatever.

There are either 1 or 2 weekends in your 7-day school cycle, depending on the start day of the cycle, so the actual cycle length is either 9 or 11 days. The Date.getDay() method gives you access to the day of the week, so a possible solutions might look like this:
var myDate= new Date();
switch(true) {
//Sunday=0, Saturday=6
case(myDate.getDay() % 6 == 0) : alert('weekend!'); return;
case (myDate.getDay() < 4) : // Mon, Tues, Wed
myDate.setDate(myDate.getDate() + 9);
break;
case (myDate.getDay() < 6) : // Thu, Fri
myDate.setDate(myDate.getDate() + 11);
break;
}

Related

generate a specific number of dates from an array of days

if I have an array of : ['Thursday', 'Friday']
and I want to generate 5 dates on the next dates of these days
for example, i want the result is the next Thursday is 14/7/2022, next Friday 15/7/2022
the output should be :
Thursday , Friday , Thursday , Friday , Thursday
=> output ['14/7/2022', '15/7/2022' , '21/7/2022' , '22/7/2022' , '28/7/2022']
If you can use libraries for that, then moment.js will help you a lot.
From that question we can create a solution for your case.
You can use moment.js to get a date from your string, and then using solution from question above get the date of that day of week on next week
This would be doable with two simple function in javascript
The first one would be to know the current date you are in ( & the day )
const d = new Date();
const day = d.getDay();
The getDay() method returns the day of the week (0 to 6) of a date.
Sunday = 0, Monday = 1, ... (See below):
More info here : https://www.w3schools.com/jsref/jsref_getday.asp.
Once you know the date, you would just need to convert your array from
['Thursday', 'Friday']
to [4,5]
Then you need to calculate the offset between the days
let offset = (targetDay - currentDayInNumber) % 7
if (offset < 0) { offset += 7 } // Want to make sure you offset is always positive
An example with tuesday = 2, thursday = 4, or monday = 1
let offset = (4 - 2) % 7 // ( 2 )
let offset = (1 - 2) % 7 // (-1)
offset = -1 + 7 // (6) we will be adding 6 days
Then you can simply loop and add days as you go
var date = new Date();
date.setDate(date.getDate() + days); // For tomorrow + 1 for example
Let me know if that helps, otherwise can provide you with the complete solution, but wanted to guide rather than give solution
-- Edit --
To complete this and to have the occurences, you could have a counter
const counterDays = {
0:0,
1:0,
..,
6:0
}
When going through the loop, everytime you setup a day, you increase the counter for it
This would be become something like this :
date.setDate(date.getDate() + offset + 7 * counterDays[targetDay]);
counterDays[targetDay]++;
I've provided you with the sample code here:
https://onecompiler.com/javascript/3y9sb8dqe
Hope this helps

How to convert date values to number of days

I am trying to add days to a date. I am taking input from the user where I have separate input boxes for the each field like no. of years, no of months and no of days like this.
as you can see in the 2nd input field row I am accepting no of years, days, months, etc.
and in First row I am getting a proper date like : 2020 10 05 00 00 00
and then passing them to date constructor to gate date.
ex. Date firstdate = new Date(2020, 10, 05, 00, 00,00);
and I am adding days to the above date using the following function
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
I am adding days to the previous date by calling a function like this.
var newdate = firstdate.addDays(totaldays);
Now the problem is while I am calculating days it is not including leap years and months with their specified date. because I am calculating days like this way:
totaldays = (years * 365) + (months * 30) + days;
What is the way so I can add days perfectly? for example, if the user entered date like
2020 12 10 00 00 00
and add the number of days and years like this
1 year 3 months 0 days 00 00 00
so it should ideally calculate 3 months that is January, February, march, as the user has entered the date of December so next three months date should be added.
SO How do I get the perfect number of days?
Sorry, this question can feel so long or improper. but I am working on this from a week.
Note: I cannot use any external link, API, Library as this is a school project.
Any help will be great. also sorry for my English. I'm not a native speaker.
Let the Date object do it for you, by using getFullyear/setFullYear, getMonth/setMonth, and getDate/setDate. They handle rollover and leap years:
const yearsToAdd = 1;
const monthsToAdd = 3;
const daysToAdd = 0;
const date = new Date(2020, 12 - 1, 10);
console.log(date.toString());
date.setFullYear(date.getFullYear() + yearsToAdd);
date.setMonth(date.getMonth() + monthsToAdd);
date.setDate(date.getDate() + daysToAdd);
console.log(date.toString());
Just as an example of handling leap years, here's that code adding two days to Feb 28th 2020 (which was a leap year, so there was a Feb 29th):
const yearsToAdd = 0;
const monthsToAdd = 0;
const daysToAdd = 2;
const date = new Date(2020, 2 - 1, 28);
console.log(date.toString());
date.setFullYear(date.getFullYear() + yearsToAdd);
date.setMonth(date.getMonth() + monthsToAdd);
date.setDate(date.getDate() + daysToAdd);
console.log(date.toString());
Notice how it goes to March 1st, not March 2nd, as it does in 2019:
const yearsToAdd = 0;
const monthsToAdd = 0;
const daysToAdd = 2;
const date = new Date(2019, 2 - 1, 28);
console.log(date.toString());
date.setFullYear(date.getFullYear() + yearsToAdd);
date.setMonth(date.getMonth() + monthsToAdd);
date.setDate(date.getDate() + daysToAdd);
console.log(date.toString());
This is a duplicate of other questions:
Add A Year To Today's Date
JavaScript function to add X months to a date
Add days to JavaScript Date
To summarise some of the issues:
Days are not always 24 hours long where daylight saving occurs, so you must determine whether "adding 1 day" means adding 1 calendar day or adding 24 hours
Months are 28 to 31 days long, so adding 1 month adds a different number of days depending on the month you're adding to
Years are 365 or 366 days long. In a leap year, adding 1 year to 29 Feb adds 366 days and ends on 2 Mar. The following day, adding 1 year to 1 Mar ends on 1 Mar
There are other quirks with leap years and month lengths not mentioned above, such as 31 Aug + 1 month gives 1 Oct, because adding a month in August adds 31 days.
So you can either add business rules to deal with the quirks, or just let them happen.
In reagard to adding years, months and days, that can be done in one call to setFullYear:
date.setFullYear(date.getFullYear() + yearsToAdd,
date.getMonth() + monthsToAdd,
date.getDate() + daysToAdd);
Adding them all at once can have a different result to adding them one at a time.
Given that you are getting values for the year, month, day, etc. then the values to add, you can simply add corresponding values (ensuring you convert strings to numbers before adding) and call the Date constructor once:
let date = new Date(startYear + yearsToAdd,
startMonth - 1 + monthsToAdd, // Assuming user enters calendar month
startDay + daysToAdd,
startHour + hoursToAdd,
startMinute + minutesToAdd,
startSecond + secondsToAdd);

How to create date object from next day of week, hh:mm and utc offset

I have these 4 input values.
Day of week: integer 0-6 (0: Sunday, 1: Monday, ... 6: Saturday)
Hours: integer 0-24
Minutes: integer 0-60
UTC offset: integer -12 - 14
With above input values, I want to create date object.
Day of week can be either of next week or this week according to current time.
Eg.
Lets assume current time is 10:00 Mon 2021.
And day of week is 1 (Monday) and Hours is 12 then this is today.
Other case, if hours is less than 10 then it would be next Monday(next week).
I have tried moment and date in javascript but I got stuck here.
Please advise me to make this createDate function
var createDate(var dow, var hh, var mm, var utc){
//return date object
}
For the date part consider the following:
function createDate(dow, hh, mm, utc) {
const date_today = moment();
const dow_today = date_today.day();
var days_dif = dow - dow_today;
if (days_dif < 0) {
console.log(moment().add(7, 'd').format('YYYY/MM/DD'));
} else {
console.log(moment().add(days_dif, 'd').format('YYYY/MM/DD'));
}
}
You'll have to add more if statements for hours and minutes if date_dif is equal to 0, otherwise just add hours and minutes to the date in the else statement.

Get the current week using JavaScript without additional libraries ? [SO examples are broken]

I built a calendar control and was adding the week numbers as a final touch, and encountered a problem with every script example I could find on SO and outside of SO (most of which one has copied from the other).
The issue is that when dates fall in partial months, the week calculation seems to mess up and either continue counting when it is the same week in a new month, or it thinks the last full week in a previous month is the same week number as the first full new week in the following month.
Following is a visual demonstration of one of the libraries (they all have their inaccuracies as they generally base their week calculation off a fixed number and build from there) :
You can view the codepen here as the project is rather complex, I have the Date.prototype.getWeek function at the start to play with this easier. Feel free to swap in any code from the samples found here on SO as they all end up funking out on some months.
Some of the calculations used :
Show week number with Javascript?
Date get week number for custom week start day
w3resource.com ISO86901
epoch calendar - getting ISO week
Get week of year in JavaScript like in PHP
When running the most current example (2017) from "Get week of year in JavaScript like in PHP", the week returned right now is 42. When you look on my calendar, the week in October right now is showing as 42 which is correct according to here https://www.epochconverter.com/weeks/2018.
Given the example, there are full weeks sharing the same week number - so I don't see how 42 can even be accurate.
Date.prototype.getWeek = function (dowOffset) {
/*getWeek() was developed by Nick Baicoianu at MeanFreePath: http://www.epoch-calendar.com */
dowOffset = typeof(dowOffset) == 'int' ? 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;
};
Here is some code (also tried this) that is Sunday specific (see near the bottom). I am also pasting the relevant snip here :
/* For a given date, get the ISO week number
*
* Based on information at:
*
* http://www.merlyn.demon.co.uk/weekcalc.htm#WNR
*
* Algorithm is to find nearest thursday, it's year
* is the year of the week number. Then get weeks
* between that date and the first day of that year.
*
* Note that dates in one year can be weeks of previous
* or next year, overlap is up to 3 days.
*
* e.g. 2014/12/29 is Monday in week 1 of 2015
* 2012/1/1 is Sunday in week 52 of 2011
*/
function getWeekNumber(d) {
// Copy date so don't modify original
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
// Set to nearest Thursday: current date + 4 - current day number
// Make Sunday's day number 7
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay()||7));
// Get first day of year
var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
// Calculate full weeks to nearest Thursday
var weekNo = Math.ceil(( ( (d - yearStart) / 86400000) + 1)/7);
// Return array of year and week number
return [d.getUTCFullYear(), weekNo];
}
The algorithm is to use the week number of the following Saturday. So get the following Saturday, then use it's year for the 1st of Jan. If it's not a Sunday, go to the previous Sunday. Then get the number of weeks from there. It might sound a bit convoluted, but it's only a few lines of code. Most of the following is helpers for playing.
Hopefully the comments are sufficient, getWeekNumber returns an array of [year, weekNumber]. Tested against the Mac OS X Calendar, which seems to use the same week numbering. Please test thoroughly, particularly around daylight saving change over.
/* Get week number in year based on:
* - week starts on Sunday
* - week number and year is that of the next Saturday,
* or current date if it's Saturday
* 1st week of 2011 starts on Sunday 26 December, 2010
* 1st week of 2017 starts on Sunday 1 January, 2017
*
* Calculations use UTC to avoid daylight saving issues.
*
* #param {Date} date - date to get week number of
* #returns {number[]} year and week number
*/
function getWeekNumber(date) {
// Copy date as UTC to avoid DST
var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
// Shift to the following Saturday to get the year
d.setUTCDate(d.getUTCDate() + 6 - d.getUTCDay());
// Get the first day of the year
var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
yearStart.setUTCDate(yearStart.getUTCDate() - yearStart.getUTCDay());
// Get difference between yearStart and d in milliseconds
// Reduce to whole weeks
return [d.getUTCFullYear(), (Math.ceil((d - yearStart) / 6.048e8))];
}
// Helper to format dates
function fDate(d) {
var opts = {weekday:'short',month:'short',day:'numeric',year:'numeric'};
return d.toLocaleString(undefined, opts);
}
// Parse yyyy-mm-dd as local
function pDate(s){
var b = (s+'').split(/\D/);
var d = new Date(b[0],b[1]-1,b[2]);
return d.getMonth() == b[1]-1? d : new Date(NaN);
}
// Handle button click
function doButtonClick(){
var d = pDate(document.getElementById('inp0').value);
var span = document.getElementById('weekNumber');
if (isNaN(d)) {
span.textContent = 'Invalid date';
} else {
let [y,w] = getWeekNumber(d);
span.textContent = `${fDate(d)} is in week ${w} of ${y}`;
}
}
Date:<input id="inp0" placeholder="yyyy-mm-dd">
<button type="button" onclick="doButtonClick()">Get week number</button><br>
<span id="weekNumber"></span>

Are there any JavaScript methods that can replicate the Oracle's ADD_MONTH() functionality

1) Oracle's example of ADD_MONTHS(date, 1):
SELECT ADD_MONTHS('30-Nov-15', 3) FROM dual;
February, 29 2016 00:00:00
2) JavaScript:
var date= new Date("Mon Nov 30 2015 00:00:00");
date.setMonth(date.getMonth() + 3);
Tue Mar 01 2016 00:00:00
Are there any JavaScript methods that can replicate the Oracle's ADD_MONTH() functionality ?
If you want to implement the same logik as in Oracle function - i.e. for "shorter" month you do not overflow in the next month, I guess you will need to do it yourself:
Pseudocode:
myDay = date.getDate(); // save the date
date.setMonth(date.getMonth() + 3); // add months
myNewDay = date.getDate();
while (myDay != myNewDay & myNewDay <= 3) {
myNewDay = myNewDay -1 // go back one day
date.setDate(myNewDay); // restore the
}
So if you end with the same day of the month after adding months you are ready.
If you get a different day of month, it will be 1,2 or 3 (the difference in month length);
go back day by day until you reach the end of the month.
This is my knowledge of the Oracle algorithm. HTH.
date.getMonth()
returns the previous months date instead of this months date. So to add to the correct date just do
date.setMonth(date.getMonth() + 2);

Categories

Resources