Moment.js - Get all mondays between a date range - javascript

I have a date range that looks like this
let start = moment(this.absence.FromDate);
let end = moment(this.absence.ToDate);
The user can decide to deactivate specific week days during that date range, so I have booleans
monday = true;
tuesday = false;
...
I want to create a function that allows me to put all mondays during my date range in an array.
I've looked around on stack but I can only find help for people who need all the monday from a month for example.

You can get next Monday using .day(1) and then loop until your date isBefore your end date adding 7 days for each iteration using add
Here a live sample:
//let start = moment(this.absence.FromDate);
//let end = moment(this.absence.ToDate);
// Test values
let start = moment();
let end = moment().add(45 , 'd');
var arr = [];
// Get "next" monday
let tmp = start.clone().day(1);
if( tmp.isAfter(start, 'd') ){
arr.push(tmp.format('YYYY-MM-DD'));
}
while( tmp.isBefore(end) ){
tmp.add(7, 'days');
arr.push(tmp.format('YYYY-MM-DD'));
}
console.log(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

Related

How to get the list of date in between start and end date using moment js [duplicate]

This question already has answers here:
How to enumerate dates between two dates in Moment
(9 answers)
Closed 2 years ago.
Get the date list based on start and end date using moment js.
For example, I have two dates, One is a start date and end date. My start date is 2019-04-02 and my end date is 2019-05-16 I need all the date in between these two dates.
My output will be ["2019-04-02", "2019-04-03", "2019-04-04", ..., "2019-05-16"] is it possible in moment js ?
This should work, but for the next time remember to add what you tried, before posting a question
var day1 = moment("2019-05-01");
var day2 = moment("2019-04-06");
var result = [moment({...day2})];
while(day1.date() != day2.date()){
day2.add(1, 'day');
result.push(moment({ ...day2 }));
}
console.log(result.map(x => x.format("YYYY-MM-DD")));
<script src="https://momentjs.com/downloads/moment.min.js"></script>
var dates = [];
var startDate = moment('2019-04-02', 'YYYY-MM-DD');
dates.push(startDate.format('YYYY-MM-DD'));
while(!startDate.isSame('2019-05-16')){
startDate = startDate.add(1, 'days');
dates.push(startDate.format('YYYY-MM-DD'));
}
console.log(dates);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.2.1/moment.min.js"></script>
Something like the following would work. We set our start and end date, create an empty array and loop through the days by adding a day per iteration, and adding the current day to our list.
var start = moment("2019-01-01")
var end = moment("2019-01-30");
var list = [];
for (var current = start; current <= end; current.add(1, 'd')) {
list.push(current.format("YYYY-MM-DD"))
}
var enumerateDaysBetweenDates = function(startDate, endDate) {
var dates = [];
var currDate = moment(startDate).startOf('day');
var lastDate = moment(endDate).startOf('day');
while(currDate.add(1, 'days').diff(lastDate) < 0) {
console.log(currDate.toDate());
dates.push(currDate.clone().toDate());
}
return dates;
};

Showing next available dates with 24h margin with Angular and MomentJS

I'm trying to display an array of possible delivery dates using AngularJS and MomentJS.
The issue is that it needs to meet certain conditions: Delivery dates are only Monday, Wednesday and Fridays.
Also, when the page loads, it recognizes the current date and it will only display the next available date that is minimum 24h away (e.g., if I load the page on a Sunday at 1pm, the first available date will be Wednesday, as Monday doesn't meet the 24h margin).
So far I could only think if dealing with the issue doing conditionals for every day of the week, but I'm pretty sure there has to be a neater way of dealing with it.
Here's what I did so far:
$scope.today = moment();
$scope.$watch('today', function () {
if ($scope.today = moment().day('Sunday')){
$scope.nextdateone = moment().add(3, 'd');
$scope.nextdatetwo = moment().add(5, 'd');
$scope.nextdatethree = moment().add(8, 'd');
$scope.nextdatefour = moment().add(10, 'd');
}
else if ($scope.today = moment().day('Monday')){
$scope.nextdateone = moment().add(2, 'd');
$scope.nextdatetwo = moment().add(4, 'd');
$scope.nextdatethree = moment().add(7, 'd');
$scope.nextdatefour = moment().add(9, 'd');
}
else if ...
});
This was the logic I came up with, but it doesn't really work as of now...
Any tips?
The delivery dates "Monday, Wednesday and Fridays", which (according to http://momentjs.com/docs/#/get-set/day/) you can represent as 1, 3 and 5.
So I would create a array with those dates, and then given the current day I would iterate that array of delivery dates to find the most suitable one... something like this:
const deliveryDates = [1, 3, 5];
const getDeliveryDate = (today) => {
let deliveryIndex = -1;
deliveryDates.some((date, index) => {
// If today is a delivery date, then schedule for the next delivery
if (today === date) {
deliveryIndex = index + 1;
return true;
}
// If today is before the current delivery date, store it
if (today < date) {
deliveryIndex = index;
return true;
}
});
// If delivery date is out of bounds, return the first delivery date
return deliveryIndex === deliveryDates.length || deliveryIndex === -1 ? 0 : deliveryIndex;
};
const getNextDelivery = (today) => {
return deliveryDates[getDeliveryDate(today)];
};
console.log(moment().day(getNextDelivery(moment().day())));
You can check a working example here:
https://jsbin.com/jawexafiji/edit?js,console

Find next instance of a given weekday (ie. Monday) with moment.js

I want to get the date of the next Monday or Thursday (or today if it is Mon or Thurs). As Moment.js works within the bounds of a Sunday - Saturday, I'm having to work out the current day and calculate the next Monday or Thursday based on that:
if (moment().format("dddd")=="Sunday") { var nextDay = moment().day(1); }
if (moment().format("dddd")=="Monday") { var nextDay = moment().day(1); }
if (moment().format("dddd")=="Tuesday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Wednesday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Thursday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Friday") { var nextDay = moment(.day(8); }
if (moment().format("dddd")=="Saturday") { var nextDay = moment().day(8); }
This works, but surely there's a better way!
The trick here isn't in using Moment to go to a particular day from today. It's generalizing it, so you can use it with any day, regardless of where you are in the week.
First you need to know where you are in the week: moment().day(), or the slightly more predictable (in spite of locale) moment().isoWeekday(). Critically, these methods return an integer, which makes it easy to use comparison operators to determine where you are in the week, relative to your targets.
Use that to know if today's day is smaller or bigger than the day you want. If it's smaller/equal, you can simply use this week's instance of Monday or Thursday...
const dayINeed = 4; // for Thursday
const today = moment().isoWeekday();
if (today <= dayINeed) {
return moment().isoWeekday(dayINeed);
}
But, if today is bigger than the day we want, you want to use the same day of next week: "the monday of next week", regardless of where you are in the current week. In a nutshell, you want to first go into next week, using moment().add(1, 'weeks'). Once you're in next week, you can select the day you want, using moment().day(1).
Together:
const dayINeed = 4; // for Thursday
const today = moment().isoWeekday();
// if we haven't yet passed the day of the week that I need:
if (today <= dayINeed) {
// then just give me this week's instance of that day
return moment().isoWeekday(dayINeed);
} else {
// otherwise, give me *next week's* instance of that same day
return moment().add(1, 'weeks').isoWeekday(dayINeed);
}
See also https://stackoverflow.com/a/27305748/800457
EDIT: other commenters have pointed out that the OP wanted something more specific than this: the next of an array of values ("the next Monday or Thursday"), not merely the next instance of some arbitrary day. OK, cool.
The general solution is the beginning of the total solution. Instead of comparing for a single day, we're comparing to an array of days: [1,4]:
const daysINeed = [1,4]; // Monday, Thursday
// we will assume the days are in order for this demo, but inputs should be sanitized and sorted
function isThisInFuture(targetDayNum) {
// param: positive integer for weekday
// returns: matching moment or false
const todayNum = moment().isoWeekday();
if (todayNum <= targetDayNum) {
return moment().isoWeekday(targetDayNum);
}
return false;
}
function findNextInstanceInDaysArray(daysArray) {
// iterate the array of days and find all possible matches
const tests = daysINeed.map(isThisInFuture);
// select the first matching day of this week, ignoring subsequent ones, by finding the first moment object
const thisWeek = tests.find((sample) => {return sample instanceof moment});
// but if there are none, we'll return the first valid day of next week (again, assuming the days are sorted)
return thisWeek || moment().add(1, 'weeks').isoWeekday(daysINeed[0]);;
}
findNextInstanceInDaysArray(daysINeed);
I'll note that some later posters provided a very lean solution that hard-codes an array of valid numeric values. If you always expect to search the same days, and don't need to generalize for other searches, that'll be the more computationally efficient solution, although not the easiest to read, and impossible to extend.
get the next monday using moment
moment().startOf('isoWeek').add(1, 'week');
moment().day() will give you a number referring to the day_of_week.
What's even better: moment().day(1 + 7) and moment().day(4 + 7) will give you next Monday, next Thursday respectively.
See more: http://momentjs.com/docs/#/get-set/day/
The following can be used to get any next weekday date from now (or any date)
var weekDayToFind = moment().day('Monday').weekday(); //change to searched day name
var searchDate = moment(); //now or change to any date
while (searchDate.weekday() !== weekDayToFind){
searchDate.add(1, 'day');
}
Most of these answers do not address the OP's question. Andrejs Kuzmins' is the best, but I would improve on it a little more so the algorithm accounts for locale.
var nextMoOrTh = moment().isoWeekday([1,4,4,4,8,8,8][moment().isoWeekday()-1]);
Here's a solution to find the next Monday, or today if it is Monday:
const dayOfWeek = moment().day('monday').hour(0).minute(0).second(0);
const endOfToday = moment().hour(23).minute(59).second(59);
if(dayOfWeek.isBefore(endOfToday)) {
dayOfWeek.add(1, 'weeks');
}
Next Monday or any other day
moment().startOf('isoWeek').add(1, 'week').day("monday");
IMHO more elegant way:
var setDays = [ 1, 1, 4, 4, 4, 8, 8 ],
nextDay = moment().day( setDays[moment().day()] );
Here's e.g. next Monday:
var chosenWeekday = 1 // Monday
var nextChosenWeekday = chosenWeekday < moment().weekday() ? moment().weekday(chosenWeekday + 7) : moment().weekday(chosenWeekday)
The idea is similar to the one of XML, but avoids the if / else statement by simply adding the missing days to the current day.
const desiredWeekday = 4; // Thursday
const currentWeekday = moment().isoWeekday();
const missingDays = ((desiredWeekday - currentWeekday) + 7) % 7;
const nextThursday = moment().add(missingDays, "days");
We only go "to the future" by ensuring that the days added are between 0 and 6.

Datejs calculate next and prev days in week

i use datejs and i want to get programme three buttons,
Today : generate two dates limites of this week, the monday and the sunday of thise week
Next : generate two dates limites of the next week
Prev : generate two dates limites of the prev week
here my code
var currentDay = 0;
(currentDay).days().fromNow().next().saturday().toString("yyyy-M-d");
(currentDay).days().fromNow().prev().monday().toString("yyyy-M-d");
the three buttons do
currentDay + 7; currentDay - 7; currentDay = 0;
the probléme is
we are monday 22, and this function return me the monday 15;
The following sample .getWeekRange() function accepts a Date object (or defaults to 'today'), will figure out the Monday of that week, then returns an object with a start and end property for the week.
Example
var getWeekRange = function (date) {
var date = date || Date.today(),
start = date.is().monday() ? date : date.last().monday(),
end = start.clone().next().sunday();
return {
start : start,
end : end
};
};
You can then use the function to acquire the week range for any given Date:
Example
var range = getWeekRange();
console.log("Start", range.start);
console.log("End", range.end);
To get the previous week, just pass in a Date object from the previous week:
Example
var prev = getWeekRange(Date.today().last().week());
To get the next week, just pass in a Date object from the next week:
Example
var next = getWeekRange(Date.today().next().week());
Hope this helps.
I've written some code for this sometime ago:
Date.prototype.getMonday=function(){return this.getDay()==1 ? this.clone().clearTime() : this.clone().prev().monday().clearTime();};
// This function returns the Monday of current week
var today=new Date();
today.getMonday().toString();
today.getMonday().next().sunday().toString();
// start and end of this week
today.getMonday().prev().monday().toString();
today.getMonday().prev().day().toString();
// previous week
today.getMonday().next().monday().toString();
today().getMonday().next().sunday().sunday().toString();
// next week
May these help.

Start and end date on multiple dates range

Hi my problem is somewhat special or maybe not. However the problem is that I parse range of dates in one array, where I need to find start date and end date where ever it may occur in ranges. I do not know did I explain this well but if you need more info, please let me know.
e.g. [2010-7-11,2010-7-12,2010-7-13, 2010-9-01, 2010-9-02,....]
Now
2010-7-11 start and 2010-7-13 end
2010-9-01 start 2010-9-02 end
So on for entire ranges within array
Thanks in advance
Here's something quick and dirty. It expects the dates array to already be sorted in ascending order.
var dates = ["2010-7-11", "2010-7-12", "2010-7-13", "2010-9-01", "2010-9-02"],
startDates = [], endDates = [],
lastDate = null, date = null;
for ( var i=0, l=dates.length; i<l; ++i ) {
date = new Date(dates[i].replace(/-/g, "/"));
//
if ( !lastDate ) {
startDates.push(lastDate = date);
}
// If the diffrence between the days is greater than the number
// of milliseconds in a day, then it is not consecutive
else if ( date - lastDate > 86400000 ) {
lastDate = null;
endDates.push(date);
}
}
// Close the last range
endDates.push(date);
// Result is two symetical arrays
console.log(startDates, endDates);

Categories