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.
Related
I am creating a Discord bot with node.js and discord.js, and there's a feature that allows users to vote thanks to a command, but I'd like them to vote only once a week.
The issue is that, on this Discord, weeks start on Friday and end on Thursday, therefore I can't simply write :
var weekNow = moment().week();
var weekLastVote = moment(dateLastVote).week();
if (weekNow == weekLastVote){
//Prevent from voting again
} else {
//Let the user vote
}
Therefore, I have written some code that seems to work, but I'd like your opinion on it as it seems very sloppy and I'm not sure if I have taken into account all of the possibilities (I don't know if I need to use my month variables for example):
module.exports = {
isSameWeek: function (dateLastVote) {
// moments for today's date
var dayNow = moment().weekday();
var weekNow = moment().week();
var monthNow = moment().month();
var yearNow = moment().year();
var dateNow = moment().format('MMDDYYYY'); // moment without hours/minutes/seconds
// moments for last vote's date
var dayLastVote = moment(dateLastVote).weekday();
var weekLastVote = moment(dateLastVote).week();
var monthLastVote = moment(dateLastVote).month();
var yearLastVote = moment(dateLastVote).year();
var dateLastVote = moment(dateLastVote).format('MMDDYYYY'); // moment without hours/minutes/seconds
if ((yearNow === yearLastVote && weekNow === weekLastVote && dayLastVote < 5) || // 5 = Friday, starting day of the week (a week = Friday to thursday)
(yearNow === yearLastVote && weekNow - 1 === weekLastVote && dayLastVote >= 5 && dayNow < 5) ||
(dateNow === dateLastVote)
){
return true;
} else {
return false;
}
}
};
As I said, this seems do to the trick but I would like someone else's opinion on it to be sure there isn't a simpler way or, if there isn't, if I haven't forgotten anything.
Thank you for reading :)
I do not know how our approaches compare to each other in matter of performance, but I still wanna show my approach on the problem:
function isSameWeek(firstDay, secondDay, offset) {
var firstMoment = moment(firstDay);
var secondMoment = moment(secondDay);
var startOfWeek = function (_moment, _offset) {
return _moment.add("days", _moment.weekday() * -1 + (_moment.weekday() >= 7 + _offset ? 7 + _offset : _offset));
}
return startOfWeek(firstMoment, offset).isSame(startOfWeek(secondMoment, offset), "day");
}
What the solution does is calculating the start of the week of each of the given dates in respect to the offset (for values >= -7 and <= 0) and returning whether both have the same start of the week. Same start of the week = same week.
All you have to do is call the function passing two date objects (or moment objects) and an offset between -7 and 0, depending on how the week is shifted in relation to a "regular" week.
I think that the best way to do want you need is to tell moment that your week starts on Friday. You can simply use updateLocale method customizing dow (day of week) key of the week object and then use your first code snippet. See Customize section of the docs to get more info about locale customization.
Here a live example of setting a custom day as first day of the week and then using your code to check if a given day is in the current week:
moment.updateLocale('en', {
week: {
dow : 5, // Friday is the first day of the week.
}
});
function checkWeek(dateLastVote){
var weekNow = moment().week();
var weekLastVote = moment(dateLastVote).week();
if (weekNow == weekLastVote){
//Prevent from voting again
console.log(moment(dateLastVote).format('YYYY-MM-DD') + ' is in the current week')
} else {
//Let the user vote
console.log(moment(dateLastVote).format('YYYY-MM-DD') + ' is NOT in the current week')
}
}
checkWeek('2017-05-30'); // same week mon-sun, but previous week fri-thu
checkWeek('2017-06-01'); // same week mon-sun, but previous week fri-thu
checkWeek('2017-06-08'); // next week mon-sun, but current week fri-thu
// First day of the current week
console.log(moment().startOf('week').format('YYYY-MM-DD'));
// Last day of the current week
console.log(moment().endOf('week').format('YYYY-MM-DD'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
EDIT An improved solution is to use moment isSame passing 'week' as second parameter. As the docs states:
Check if a moment is the same as another moment.
If you want to limit the granularity to a unit other than milliseconds, pass it as the second parameter.
Here a live sample:
moment.updateLocale('en', {
week: {
dow : 5, // Friday is the first day of the week.
}
});
function isSameWeek(dateLastVote){
var now = moment();
var lastVote = moment(dateLastVote);
if (now.isSame(lastVote, 'week')){
//Prevent from voting again
console.log(moment(dateLastVote).format('YYYY-MM-DD') + ' is in the current week')
} else {
//Let the user vote
console.log(moment(dateLastVote).format('YYYY-MM-DD') + ' is NOT in the current week')
}
}
isSameWeek('2017-06-10'); // same week mon-sun, but next week fri-thu
isSameWeek('2017-06-03'); // previous week mon-sun, but current week fri-thu
isSameWeek('2017-06-06'); // current week both mon-sun and fri-thu
// First day of the current week
console.log(moment().startOf('week').format('YYYY-MM-DD'));
// Last day of the current week
console.log(moment().endOf('week').format('YYYY-MM-DD'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
According to the Moment docs you can set the ISO start of the week:
moment().isoWeekday(1); // Monday
moment().isoWeekday(7); // Sunday
then you can use the same functionality to check if the days are in the same week of the year.
Take a look:
https://momentjs.com/docs/#/get-set/iso-weekday/
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
I seem to have a bit of a problem getting the previous Monday given a particular date. I'm trying to use Moment js for the task. Obviously, I can do it by hand, but found it curious that I couldn't get it to work using the example in the moment.js documentation on their website: http://momentjs.com/docs/#/get-set/day/.
I was trying something like:
moment([2013, 08, 15, 15, 20]).day(-1).format('ddd, MMM DD')
which results in the 'two days ago' date, that being September 13 instead of the expected September 9th.
Does anybody have a clue here? Thanks.
Here is how it works:
moment().day(1) // this monday
moment().day(-6) // last monday, think of it as this monday - 7 days = 1 - 7 = -6
Same applies in other direction:
moment().day(8) // next monday, or this monday + 7 days = 1 + 7 = 8
Your code moment().day(-1) can be explained as this Sunday - 1 day = 0 - 1 = -1
or this Saturday - 7 days = 6 - 7 = -1
The accepted answer only works if you already know whether the day in question is in this week or next week. What if you don't know? You simply need the next available Thursday following some arbitrary date?
First, you want to know if the day in question is smaller or bigger than the day you want. If it's bigger, you want to use the next week. If it's smaller, you can use the same week's Monday or Thursday.
const dayINeed = 4; // for Thursday
if (moment().isoWeekday() <= dayINeed) {
return moment().isoWeekday(dayINeed);
} else...
If we're past the day we want already (if for instance, our Moment is a Friday, and we want the next available Thursday), then you want a solution that will give you "the Thursday of the week following our moment", regardless of what day our moment is, without any imperative adding/subtracting. In a nutshell, you want to first go into the next week, using moment().add(1, 'weeks'). Once you're in the following week, you can select any day of that week you want, using moment().day(1).
Together, this will give you the next available day that meets your requirements, regardless of where your initial moment sits in its week:
const dayINeed = 4; // for Thursday
// if we haven't yet passed the day of the week that I need:
if (moment().isoWeekday() <= 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 day
return moment().add(1, 'weeks').isoWeekday(dayINeed);
}
See also: https://stackoverflow.com/a/27305748/800457
function nextWeekday (day, weekday) {
const current = day.day()
const days = (7 + weekday - current) % 7
return day.clone().add(days, 'd')
}
// example: get next Friday starting from 7 Oct 2019
nextWeekday(moment('2019-10-07'), 5)) // 2019-10-11
I think the point is that using day() or isoWeekday() you get a date in the current week, no matter which day of the week is today. As a consequence, the date you get can be past, or still to come.
Example:
if today is Wednesday, moment().isoWeekday(5).format() would return the date of the upcoming Friday.
While
moment().isoWeekday(1).format() would return the previous Monday.
So when you say you want the date of, let's say, "last Tuesday", this date could belong to the current week or to the previous week, depending on which day is today.
A possible function to get the date of the last dayOfTheWeek is
function getDateOfPreviousDay(dayOfTheWeek) {
currentDayOfTheWeek = moment().isoWeekday();
if ( currentDayOfTheWeek >= dayOfTheWeek ) {
return moment().isoWeekday(dayOfTheWeek).format(); // a date in the current week
}
else {
return moment().add(-1,'weeks').isoWeekday(dayOfTheWeek).format(); // a date in the previous week
}
}
const upcomingDay = (dayIndex, format = "DD MMMM YYYY") => {
if (
Number(moment().format("D")) >= Number(moment().day(dayIndex).format("D"))
) {
return moment()
.day(7 + dayIndex)
.format(format);
}
return moment().day(dayIndex).format(format);
};
Is there a simple/built in way of figuring out the current financial quarter?
ex:
Jan-Mar: 1st
Apr-Jul: 2nd
Jul-Sept: 3rd
Oct-Dec: 4th
This is now supported in moment:
moment('2014-12-01').utc().quarter() //outputs 4
moment().quarter(); //outputs current quarter ie. 2
Documentation
Using version 2.14.1+ you can do something like the following:
moment().quarter() returns the current quarter number: 1, 2, 3, 4.
moment().quarter(moment().quarter()).startOf('quarter');
Would return the current quarter with the date set to the quarter starting date.
moment().quarter(moment().quarter()).startOf('quarter');
Would return the current quarter with the date set to quarter ending date.
You could also define a function that takes the corresponding quarter number as argument (1,2,3,4), and returns an object containing the start and end date of the quarter.
function getQuarterRange(quarter) {
const start = moment().quarter(quarter).startOf('quarter');
const end = moment().quarter(quarter).endOf('quarter');
return {start, end};
}
Use this simple code to get all quarter based on january and april
Demo
Code :
// startMonth should be january or april
function setQuarter(startMonth) {
var obj = {};
if(startMonth=='january'){
obj.quarter1 = {start:moment().month(0).startOf('month'),end:moment().month(2).endOf('month')}
obj.quarter2 = {start:moment().month(3).startOf('month'),end:moment().month(5).endOf('month')}
obj.quarter3 = {start:moment().month(6).startOf('month'),end:moment().month(8).endOf('month')}
obj.quarter4 = {start:moment().month(9).startOf('month'),end:moment().month(11).endOf('month')}
console.log(obj);
return obj;
}
else if(startMonth=='april'){
obj.quarter1 = {start:moment().month(3).startOf('month'),end:moment().month(5).endOf('month')}
obj.quarter2 = {start:moment().month(6).startOf('month'),end:moment().month(8).endOf('month')}
obj.quarter3 = {start:moment().month(9).startOf('month'),end:moment().month(11).endOf('month')}
obj.quarter4 = {start:moment().month(0).startOf('month').add('years',1),end:moment().month(2).endOf('month').add('years',1)}
console.log(obj);
return obj;
}
}
setQuarter('april');
Fiddle
START DATE
moment().quarter(moment().quarter()).startOf('quarter');
Would return the current quarter with the date set to the quarter starting date.
moment("2019", "YYYY").quarter(4).startOf('quarter');
Would return the starting date of the 4th quarter of the year "2019".
moment().startOf('quarter');
Would return the starting date of the current quarter of current year.
END DATE
moment().quarter(moment().quarter()).endOf('quarter');
Would return the current quarter with the date set to quarter ending date.
moment("2019", "YYYY").quarter(4).endOf('quarter');
Would return the ending date of the 4th quarter of the year "2019".
moment().endOf('quarter');
Would return the ending date of the current quarter of current year.
I dont think any of these answers explain how to get the financial quarter. They explain how to get the calendar quarter.
I do not have a clean answer as thats what led me here. But the fiscal quarter is what is really wanted. And that is based on the start month of the fiscal year.
For example if my company's fiscal start month is February. Then at the time of writing this January 9th 2017 I'm actually in Q4 2016.
To accomplish this we need a way to get the quarter relative to a supplied integer of the start month.
There is nothing built in right now, but there is conversation to add formatting tokens for quarters. https://github.com/timrwood/moment/pull/540
In the meantime, you could use something like the following.
Math.floor(moment().month() / 3) + 1;
Or, if you want it on the moment prototype, do this.
moment.fn.quarter = function () {
return Math.floor(this.month() / 3) + 1;
}
The formula that seems to work for me is:
Math.ceil((moment().month() + 1) / 3);
moment().month() gives back the 0-11 month format so we have to add one
THE ACTUAL MONTH = (moment().month() + 1)
then we have to divide by 3 since there are 3 months in a quarter.
HOW MANY QUARTERS PASSED = (THE ACTUAL MONTH) / 3
and then we have to get the ceiling of that (round to the nearest quarter end)
CEILING(HOW MANY QUARTERS PASSED)
EDIT:
The Official formula (not commited yet) is:
~~((this.month()) / 3) + 1;
which means Math.floor((this.month()) / 3) + 1;
The simplist way to do this is
Math.floor(moment.month() / 3)
That will give you the zero based quarter index. ie 0, 1, 2, or 3.
Then, if you want the quarter's literal number, just add one.
Answer given by Nishchit Dhanani, is correct but has one issue in 'April' scenario.
Issue: If your financial year is April than, For first 3 months i.e. JAN, FEB & MAR
obj.quarter1.start date returns, 1-April-CurrentYear [incorrect Value]
obj.quarter4.end date retunrs, 31-March-NextYear [incorrect Value]
Correct values should be,
Start = 1-April-PreviuosYear
End = 31-March-CurrentYear
So, Taking consideration for first 3 month it can be written something like,
const obj = {};
/* 0-Jan, 1-Feb, 2-Mar */
if (moment().month() <= 2) {
obj.quarter1 = { start: moment().month(3).startOf('month').add('years', -1), end: moment().month(5).endOf('month').add('years', -1) };
obj.quarter2 = { start: moment().month(6).startOf('month').add('years', -1), end: moment().month(8).endOf('month').add('years', -1) };
obj.quarter3 = { start: moment().month(9).startOf('month').add('years', -1), end: moment().month(11).endOf('month').add('years', -1) };
obj.quarter4 = { start: moment().month(0).startOf('month'), end: moment().month(2).endOf('month') };
} else {
obj.quarter1 = { start: moment().month(3).startOf('month'), end: moment().month(5).endOf('month') };
obj.quarter2 = { start: moment().month(6).startOf('month'), end: moment().month(8).endOf('month') };
obj.quarter3 = { start: moment().month(9).startOf('month'), end: moment().month(11).endOf('month') };
obj.quarter4 = { start: moment().month(0).startOf('month').add('years', 1), end: moment().month(2).endOf('month').add('years', 1) };
}
console.log(obj);
I am trying to create a simple script that gives me the next recycling date based on a biweekly schedule starting on Wed Jul 6, 2011. So I've created this simple function...
function getNextDate(startDate) {
if (today <= startDate) {
return startDate;
}
// calculate the day since the start date.
var totalDays = Math.ceil((today.getTime()-startDate.getTime())/(one_day));
// check to see if this day falls on a recycle day
var bumpDays = totalDays%14; // mod 14 -- pickup up every 14 days...
// pickup is today
if (bumpDays == 0) {
return today;
}
// return the closest day which is in 14 days, less the # of days since the last
// pick up..
var ms = today.getTime() + ((14- bumpDays) * one_day);
return new Date(ms);
}
and can call it like...
var today=new Date();
var one_day=1000*60*60*24; // one day in milliseconds
var nextDate = getNextDate(new Date(2011,06,06));
so far so good... but when I project "today" to 10/27/2011, I get Tuesday 11/8/2011 as the next date instead of Wednesday 11/9/2011... In fact every day from now thru 10/26/2011 projects the correct pick-up... and every date from 10/27/2011 thru 2/28/2012 projects the Tuesday and not the Wednesday. And then every date from 2/29/2012 (leap year) thru 10/24/2012 (hmmm October again) projects the Wednesday correctly. What am I missing? Any help would be greatly appreciated..
V
The easiest way to do this is update the Date object using setDate. As the comments for this answer indicate this isn't officially part of the spec, but it is supported on all major browsers.
You should NEVER update a different Date object than the one you did the original getDate call on.
Sample implementation:
var incrementDate = function (date, amount) {
var tmpDate = new Date(date);
tmpDate.setDate(tmpDate.getDate() + amount)
return tmpDate;
};
If you're trying to increment a date, please use this function. It will accept both positive and negative values. It also guarantees that the used date objects isn't changed. This should prevent any error which can occur if you don't expect the update to change the value of the object.
Incorrect usage:
var startDate = new Date('2013-11-01T11:00:00');
var a = new Date();
a.setDate(startDate.getDate() + 14)
This will update the "date" value for startDate with 14 days based on the value of a. Because the value of a is not the same is the previously defined startDate it's possible to get a wrong value.
Expanding on Exellian's answer, if you want to calculate any period in the future (in my case, for the next pay date), you can do a simple loop:
var today = new Date();
var basePayDate = new Date(2012, 9, 23, 0, 0, 0, 0);
while (basePayDate < today) {
basePayDate.setDate(basePayDate.getDate()+14);
}
var nextPayDate = new Date(basePayDate.getTime());
basePayDate.setDate(nextPayDate.getDate()-14);
document.writeln("<p>Previous pay Date: " + basePayDate.toString());
document.writeln("<p>Current Date: " + today.toString());
document.writeln("<p>Next pay Date: " + nextPayDate.toString());
This won't hit odd problems, assuming the core date services work as expected. I have to admit, I didn't test it out to many years into the future...
Note: I had a similar issue; I wanted to create an array of dates on a weekly basis, ie., start date 10/23/2011 and go for 12 weeks. My code was more or less this:
var myDate = new Date(Date.parse(document.eventForm.startDate.value));
var toDate = new Date(myDate);
var week = 60 * 60 * 24 * 7 * 1000;
var milliseconds = toDate.getTime();
dateArray[0] = myDate.format('m/d/Y');
for (var count = 1; count < numberOccurrences; count++) {
milliseconds += week;
toDate.setTime(milliseconds);
dateArray[count] = toDate.format('m/d/Y');
}
Because I didn't specify the time and I live in the US, my default time was midnight, so when I crossed the daylight savings time border, I moved into the previous day. Yuck. I resolved it by setting my time of day to noon before I did my week calculation.