Getting the next date for a specific day of the week - javascript

Given a start date of 2014-07-08 (Tuesday) I would want to perform a check to find the closest day of the week.
For example, I need to be able to perform the following calls:
First Monday (should return 2014-07-14)
First Wednesday (should return 2014-07-09)
First Saturday (should return 2014-07-12)
Etc.
I know moment.js lets you do something like
moment("2014-07-08").day(1)
To get the date of Monday this week, however I need to know if the DOW is before/after the current date and apply the offset accordingly; if that makes any sense..
Any thoughts?

Just add 7 if the day of the week you are looking for is or was before the current day of the week:
var date = moment("2014-07-08");
var dow = date.day();
var nextX = date.day(X + dow <= X ? 7 : 0);

Related

Compute an age with d3-time

I'm trying to compute the age of an individual using D3.js.
I have the following code :
d3.timeYear.count(Birth_date, Current_date);
Birth_date being an individual's birth date (a Date object), and Current_date being, well, the date at which I'd like to compute the individual's age. To be able to answer "if you were born on May 5th, 1975, how old were you on May 3rd, 1976".
d3.timeYear.count() seems to floor the dates to the beginning of the year, so that in my example my code will return 1 on January 1st, 1976, even though the guy was 5 months away from his first birthday.
I could count the number of days instead of years, but I might get wrong results locally depending on the number of days in the year.
The following is based on the JavaScript Date object and should do the job:
function age(by,bm,bd){
const D=new Date(), y=D.getFullYear(),
md=D.getMonth()-bm, dd=D.getDate()-bd;
return y-by-(md>0||!md&&dd>=0?0:1);
}
console.log(age(1992,8,26))
Basically I return the difference between the full year of today and the birthday. But I also check, whether the current month is either greater than the birthday-month or (||) if the month-difference is zero (!md is true) and (&&) the day-difference dd is greater than zero. If that is the case I subtract 0 otherwise 1 from the year-difference.
And please be aware that my age() function expects the month to be entered in JavaScript notation. This means that 8 in the above example refers to the month of September.
The answer by Carsten Massman has inspired me to make this function, which solves my problem :
function age(birthdate, currentdate){
const bDay = birthdate.getDate(); // Get the birthdate's day.
const bMonth = birthdate.getMonth(); // Get the birthdate's month.
const currYear = currentdate.getFullYear(); // Get the current date's year.
const currBirthday = new Date(currYear + "/" + (bMonth + 1) + "/" + bDay); // Contruct the date of the birthday in the current year
const daysToBirthday = d3.timeDay.count( d3.timeYear.floor(currBirthday), currBirthday); // Count the # of days since Jan. 1st this year
// Offset the current date in the past by the number of days computed above.
const offsetCurrent = d3.timeDay.offset(currentdate, -daysToBirthday);
// Compute the number of years between the two dates (floored to the beginning of their respective year).
return d3.timeYear.count(birthdate, offsetCurrent);
}
This computes the age for any birth date, and at any point in time afterwards, using mostly d3-time and a little bit of vanilla javascript's Date methods.

How many saturdays and sundays between two dates with JS and Input Form

I am trying to get how many saturdays and sundays exist between two dates.
I get the first date from a input date field
<input value="" type="date" name="exit_end_document" id="exit_end_document" class="form-control" required>
My Javascript is this:
var fromDate = $('#exit_end_document').val();
I am getting the value.. the problem is that i do not know how can i calculate between that date which i get from input date field and today.
I have seen many examples but none of them do this...
(input date field) 2019-03-01 to (This date comes directly from JS) 2019-03-05 result = 2
Thanks!
Let's analyze this mathematically.
The starting date can either be on a Saturday or not. Likewise, the ending date can be either on a Saturday or not. In the simplest case, both dates are on Saturday; then you can see clearly that the number of Saturdays is equal to 1 plus the number of weeks between the two dates.
From there, it's easy to see that if the starting date is on a Saturday, but the ending date is not, then the number of Saturdays is equal to 1 plus the number of weeks between the two dates rounded down since the ending date's week has not reached Saturday yet. Turns out, that same math works for the first example, too, since you'll have an integer number of weeks between the dates. So we can cover both examples by simply using 1 + floor(weeks_between_dates) .
What if the ending date is a Saturday, but the starting date is not? Turns out, the math still works the same! This is the same as "moving back" the starting date from its Saturday, and that will add a partial week until it reaches the previous Saturday. Those partial weeks get rounded out by the floor, and once it reaches the previous Saturday, you'll be adding 1 anyway, as it'll be a full week added to the difference! So we're still good with 1 + floor(weeks_between_dates).
So the only possible combination left are two dates which are both not Saturday. This is the most complicated possibility. Let's start simple and assume the dates are two consecutive Wednesdays. Then they are 1 week apart and have 1 Saturday between them. Simple. If they're two weeks apart, they have 2 Saturdays. But what if it's a Wednesday and the following Tuesday? There is less than a week, but still 1 Saturday between them. And if it's a Wednesday and the following Thursday? More than 1 week, but still 1 Saturday! So in this case, we'd want to round the number of weeks up and stop there, giving us ceil(weeks_between_dates). But if they're both in the same week -- for instance, a Monday and a Friday in the same week -- then the answer is just 0. So how do we know whether the days are part of the same week? Assuming they're sorted and the start date is always before the ending date, then they're in the same week if and only if there is fewer than 1 week between them AND the starting weekday is before the ending weekday.
So the straight conditional logic here is this (in pseudocode):
weeks_between = floor((days between start and end) / 7)
if start.weekday = Saturday or end.weekday = Saturday, then:
return 1 + weeks_between
else if weeks_between = 0 and start.weekday is before end.weekday, then:
return 0
else
return ceil((days between start and end) / 7)
In order to handle leap years and timezones and whatnot, i suggest testing all the between days and testing them to see if they are sat or sunday:
var date1 = new Date("2012-06-04T05:00:00.000Z");
var date2 = new Date("2012-08-17T05:00:00.000Z");
var weekendDays = 0;
for(var i = +date1, mx = +date2; i<mx; i+=(1000*60*60*24)){
if({0:1,6:1}[new Date(i).getDay()]) weekendDays++;
}
alert(weekendDays); // 20
I already found the solution and it was given from #zak:
var fromDate = $('#exit_end_document').val();
fromDate = new Date(fromDate);
toDate = new Date();
var weekendDays = 0;
dayMilliseconds = 1000 * 60 * 60 * 24;
date1 = fromDate;
date2 = toDate;
while (date1 <= date2) {
var day = date1.getDay();
if (day == 0 || day == 6) {
weekendDays++;
}
date1 = new Date(+date1 + dayMilliseconds);
}
alert(weekendDays);

Get the next time that respect a time format and not a pervious one

I am trying to get the time to the next "6:00:00", I am using moment:
let shiftEnd = moment("06:00:00", "HH:mm:ss")
console.log(shiftEnd.inspect())
It gets me the previous 6:00:00, the one with the same day as now().
moment("2017-07-31T06:00:00.000")
now() is:
moment("2017-07-31T12:20:57.076")
What's the best way to get the next 6am that's not passed yet?
You are getting a moment object for the current day because, as moment Default section states:
You can create a moment object specifying only some of the units, and the rest will be defaulted to the current day, month or year, or 0 for hours, minutes, seconds and milliseconds.
You can simply test if your moment object is in the past (using isBefore) and add 1 day if needed.
Here a live example:
let shiftEnd = moment("06:00:00", "HH:mm:ss")
if( shiftEnd.isBefore(moment()) ){
shiftEnd.add(1, 'd')
}
console.log(shiftEnd.inspect())
console.log(shiftEnd.format())
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
You could use day method to get the current day of week number, and then add one to the day of the week to get tomorrow day of week:
var now = moment(), day;
// check if before 6 am get the current day, otherwise get tomorrow
if(now.hour() < 6)
day = now.day();
else
day = now.day() + 1;
Then to get tomorrow 6 am use isoWeekDay to get the moment object from the number of the day of week and set hour to 6 and minutes and seconds to 0:
var tomorrow = moment().isoWeekday(day).hour(6).minute(0).second(0)
tomorrow will be 2017-08-01T06:00:00+02:00

Get the first day of the week from a previously selected week

I have a datepicker plugin where I get the day of the week (so far everything is fine and working). If I click again in the week field, the datepicker opens, but the selected day is today's (the current day). What I want is when I click in datepicker, its select the first day of the week select (Monday).
For example, if I have chosen the week 28 of 2017, I want the day July 10, 2017 to appear selected when I click the datepicker
You can try a simple logic.
Accept week number and multiply it by 7. You will have nth day.
Create a variable (baseDay) that will hold the day to be selected.
Create a date object for this day.
Now fetch the day of this date and subtract baseDay from it. You will get number of days to subtract to get necessary date.
Subtract those days and you have your date.
function getStartOfWeek(weekNo) {
var baseDay = 1; // For Monday
var today = new Date();
var date = new Date(today.getFullYear(), 0, weekNo * 7);
var day = date.getDay();
console.log(date, date.getDay())
if (day > baseDay)
date.setDate(date.getDate() - (day - baseDay))
console.log(date, date.getDay())
}
getStartOfWeek(28)
Note: this is not the complete solution. Above logic is to get the necessary date. Once you have a date, you will have to set it to the datepicker. This part will be specific to plugin used and can be incorporated easily.

JavaScript: Convert Day/Week Into Year

I have been using Stack Overflow for a number of months now, but this is my first post.
I require a function to convert a week number and and day of week into a dd/mm/yyyy format.
The date values i have to work with are in the format day/weekNumber. So for example: 3/43 converts to Wednesday 24 October 20XX. The year value will be the current year.
The day value starts at 1 (Monday).
I have found lots of functions on the internet (such as this, this and this). Some work with ISO 8601 dates, which i do not think will work for me. And i have not yet found one that works for me.
Thanks in advance,
This solution does require an extra library to be added, but I think it is really worth it. It is a momentjs library for manipulating dates and time. It is actively maintained and has a great documentation. Once you get the values for day and weekNumber (in our case 3 and 43), you should do as follows:
function formatInput(day, weekNumber){
var currentDate = moment(new Date()); // initialize moment to a current date
currentDate.startOf('year'); // set to Jan 1 12:00:00.000 pm this year
currentDate.add('w',weekNumber - 1); // add number of weeks to the beginning of the year (-1 because we are now at the 1st week)
currentDate.day(day); // set the day to the specified day, Monday being 1, Sunday 7
alert(currentDate.format("dddd, MMMM Do YYYY")); // return the formatted date string
return currentDate.format("dddd, MMMM Do YYYY");
}
I think this library might be useful to you later on and there are plenty of possibilities regarding date and time manipulation, as well as formatting options. There is also a great documentation written for momentjs.
So assuming you have the values of 3 and 43 separately, you can just do some simple maths on the first day of the current year:
Get 1st January Current Year
Add (43 * 7 + 3)
Something like this maybe:
var currentDate = new Date();
var startOfYear = new Date(currentDate.getFullYear(), 0, 1);//note: months start at 0
var daysToAdd = (43 * 7) + 3;
//add days
startOfYear.setDate(startOfYear.getDate() + daysToAdd);
Here is an example
EDIT
On second thoughts, I think I was wrong with your requirements. It seems you require a specific day of the week. Check this out for a better solution.
The problem is that it all depends on your definition of a week. This year starts on a sunday, so does that mean that 02/01/2012 (the first monday of this year) is the start of the second week?
My latest example will first find the start of the specified week, and then find the next occurrence of the specified day
According to ISO when dealing with week dates, the week starts on Monday and the first week of the year is the one that contains the first Thursday of the year. So for 2012, the first week started on Monday, 2 January and the first week of 2013 will start on Monday, 31 December 2012.
So if 3/43 is the third day of the 43rd week (which is the ISO date 2012-W43-3), then it can be converted it to a date object using:
function customWeekDateToDate(s) {
var d, n;
var bits = s.split('/');
// Calculate Monday of first week of year this year
d = new Date();
d = new Date(d.getFullYear(),0,1); // 1 jan this year
n = d.getDay();
d.setDate(d.getDate() + (-1 * n +( n<5? 1 : 8)));
// Add days
d.setDate(d.getDate() + --bits[0] + --bits[1] * 7);
return d;
}
console.log(customWeekDateToDate('3/43')); // 01 2012-10-24
Note that this uses dates, otherwise daylight saving changeovers may result in the wrong date.

Categories

Resources