I am creating a platform for recurring monthly orders.
I am using later.js for the recurrence. I have come across the following two cases and I am wondering if anybody has suggestions on how to better handle these (or if later.js handles them natively somehow):
later.parse.recur().on(31).dayOfMonth()
The date is the 31st of a given month. Current result is that is jumps months that end on the 30th. WORKAROUND: is to use last().dayOfMonth().
later.parse.recur().on(30).dayOfMonth()
later.parse.recur().on(31).dayOfMonth()
Month of February, ending on the 28th or 29th. How to handle if the date is 30th (or 31st). WORKAROUND: If date > 28th, add .and().on(59).dayOfYear()
Thanks!
I don't know the specifics of later.js, but apparently you can write something called a custom modifier: https://github.com/bunkat/later/blob/master/example/modifier.js
In addition to this, if you add a month to a javascript date (doesn't matter if the number becomes greater than 11/december), set the day of the month to the first then subtract 1 day, then you'll get the date of the last day in the originally given month. For example:
var a = new Date("2000-02-25");
var b = new Date(new Date(a.getFullYear(),a.getMonth()+1,1)-1);
console.log(b);
Related
I'm using the moment.js library to plot some values on a graph. I have two buttons called Previous and Next that go one month behind and one month forward from the current date respectively.
Now, the issue that I am facing is with the subtract function - for example, since today is February - the endOf('month') function moves up to 28 days. Now, if I wish to move a month back to January, I am using the following :
moment().endOf('month').subtract(1,'month'+ 's');
This does move back to January, but the date endOf date is still 28 - and due to this my graph only plots until this day of January.
Is there a way I can check for the month and set in the correct last date as I move behind or forward using the subtract function? Or am I missing out on something?
Here is a simple fiddle - I'm alerting the value after using the moment functions.
Subtract 1 month before using endOf.
So I am kinda stuck in figuring out a certain aspect. What I want to do is the following:
Let's say I just have a simple date display, which will show a date such as October 10th, 2017 to an end user. And then there is an option to subtract a certain number of days from said date (an offset of 1, 2, 3, whatever offset is chosen).
What I am looking to do is completely exclude weekend dates from the count - so if today is Monday, October 9th, and an offset of 1 is selected, it goes to Friday the 6th; if an offset of 2 is chosen, it goes to Thursday the 5th; an offset of 3 goes to Wednesday the 4th...
If today was Wednesday, October 11th, an offset of 2 would take you to Monday the 9th, an offset of 4 would go to Thursday the 5th, and so on (completely disregards / skips weekend dates when counting / subtracting which day to land on).
I have so far been able to only find answers for the functionality to calculate the number of working days excluding weekends, and things of that nature (which I already have, using the momentjs-business npm module, but is not exactly what I need).
I did not post code because this is part of a much larger code base, and I feel posting snippets would only add to the confusion, since I believe the question is relatively simply and straightforward; I do not want to over complicate.
All I would like is to not include weekends at all when setting an offset from whichever date is displayed to the user (the date which is displayed to the user is from a database).
I hope this all made sense, and if more info is needed, please let me know. Thanks in advance for anyone that can point me in the right direction!
This will achieve what you want I think. Please note this is terribly inefficient. If your offset is very large it generates a new date every iteration of the loop. With some tinkering it could be optimized
let startDate = new Date('10/10/2017');
let endDate = "", offset = 2;
while(offset > 0){
endDate = new Date(startDate.setDate(startDate.getDate() - 1));
if(endDate.getDay() !== 0 && endDate.getDay() !== 6){
offset--;
}
}
Here is a working Fiddle
You can use moment-business library. It has the subtractWeekDays that:
Subtract week days from the moment, modifying the original moment. Returns the moment.
Your code could be like the following:
var m = moment("October 10th, 2017", "MMMM Do, YYYY");
business.subtractWeekDays(m, 2);
If you don't want to add an external library, have a look at addWeekDays and subtractWeekDays code.
JavaScript date objects have a getDay() method that tells you what day of the week it is. You could use this to figure out which dates are weekends and exclude them.
var date = new Date();
var dayOfWeek = date.getDay();
console.log(dayOfWeek) // 1 for Monday, 2 for Tuesday, etc.
I'm trying to validate a uk date using this code:
function ukdate(d) {
var p = new Date(d.split('/')[2], d.split('/')[1] -1, d.split('/')[0]);
if(p.toString() !== 'Invalid Date') {
return p;
}
}
http://jsfiddle.net/GE3xU/1/
so if I try ukdate('31/12/1981') it correctly returns "The Dec 31 1981". However if i try ukdate('12/31/1981') it returns "Tue Jul 12 1983".
Why is this happening? I'm expecting the second test to return invalid date because 31 is not a valid month.
JavaScript is converting your date for you.
In simple examples, you can get the last day of a given month by asking for the 0th day of the following month. Similarly, the "32nd of August" would be corrected to the 1st of September.
Months work similarly. The 13th month of a given year is the 1st month of the next. The 0th month of a year is December of the previous.
31 % 12 = 7, hence July, and floor(31/12) = 2 hence the year being shifted forward by two.
This is intended behaviour for JavaScript.
May I interest you in <input type="date" />? It uses whatever format is defined on the user's computer (ie. it is "locale-aware"), which is already excellent for user experience. On top of that, supporting browsers will render a calendar date picker, especially useful on phones too. Internally, the date is in "standard" YYYY-mm-dd format.
The month value is divided by 12 and added to the year, then the remainder is used as the actual month value.
See the spec
Let ym be y + floor(m /12).
Let mn be m modulo 12.
I'm working on a jQuery credit card expiration date validation script. Credit cards expire after the last day of the expiration month. For instance, if the card expires on 8/2013 then it's good through 8/31/2013.
In the past on the server side I've determined the last day of the month by adding 1 to the current month, then subtracting 1 day.
Today I noticed that when creating a new date, if 0 is applied to the 3rd parameter of the JavaScript Date() object, the resulting date will be the end-of-month day. But I've been unable to locate any online documentation to affirm this observation.
Here is some sample code.
var month = 10;
var year = 2013;
var expires = new Date(year, month, 0);
alert(expires);
And here is a jsFiddle example that I created.
This is a bit confusing, because I thought in JavaScript months were zero based. I've tested this in Chrome, Firefox, IE, and Safari, and the behavior appears consistent. The returned date consistently displays the last day of the month. This looks like a lucky find, but I'd really like to understand what is happening here.
Am I safe to run with this approach to assigning an end of month date, and if so is there some online documentation that I can point to which affirms this? Thanks.
Months are zero-based. That creates an end-of-month date in the previous month. Month 10 is November, so creating a date with day 0 in November gives you the end of October (month 9).
That is, day 0 in November means "the day before 1 November", which is the last day of October. Day -1 in November would be 30 October.
I am currently writing some sort of javascript based client calendar and observed some issues. All over the net, I can find code samples, where people use day overflows in the Date constructor.
i.e.
// get the first day of the next month
var myDate = new Date(someDate.getFullYear(),someDate.getMonth(),32);
myDate.setDate(1);
The general idea of this concept is, that since there is no month with 32 days, the constructor will create a date within the next month. I saw even codesample with negative overflows:
i.e.
// get the last day of the previous month
var myDate = new Date(someDate.getFullYear(),someDate.getMonth(),1);
myDate.setDate(-1);
Now while this seems to work in many cases, I finally found a contradiction:
// this prints "2012-12-30" expected was "2012-12-31"
var myDate = new Date(2013,0,1);
myDate.setDate(-1);
Further examination finally revealed that dates like
new Date(2013,0,23) or new Date(2013,0,16) combined with setDate(-1) all end up in "2012-12-31". Finally I observed that using -1 seems to subtract two days (for getting the expected result setDate(0) has to be used).
Is this a bug in the browser implementations or are the code samples spread accross the internet crap??
Furthermore, is this setDate with positive and negative overflow secure to be used and uniformly implemented by all major browsers?
From MDN:
If the parameter you specify is outside of the expected range, setDate attempts to update the date information in the Date object accordingly. For example, if you use 0 for dayValue, the date will be set to the last day of the previous month.
It's logical if you think about it: setDate(1) sets the date to the first of the month. To get the last day of the previous month, that is, the day before the first of this month, you subtract one from the argument and get 0. If you subtract two days (1 - 2) you get the second to last day (-1).
are [..] code samples spread accross the internet crap?
Yes. This is true at least 90% of the time.
At MDN they say:
If the parameter you specify is outside of the expected range, setDate
attempts to update the date information in the Date object
accordingly. For example, if you use 0 for dayValue, the date will be
set to the last day of the previous month.
So you're getting coherent results:
1 - Jan 1
0 - Dec 31
-1 - Dec 30
-2 - Dec 29
Edit: It may look counter-intuitive if you think of it as a mere relative value, such as PHP's strtotime() function:
strtotime('-1 day');
It's not the case ;-)