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.
Related
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've came across something that I thought it was right, but now taking a closer look something is clearly wrong.
I'm on a project of a pill reminder app where someone can set notifications to remind him/her of taking pills in the correct time. There're medicines which a person can take for the rest of his life. And in that case I don't set alerts for years, I set for 3 months max and, when he takes one and mark it as done, I set another alert for 3 months later starting on that date/time.
This app will be released only in Brazil and we have Daylight Saving Time here. When it shifts to DST time the clocks must be adjusted to -1 hour after midnight, when going off DST it gains 1 hour.
For this project I'm using Firebase, Ionic 2, the LocalNotification Plugin and Moment JS.
I have to make a story of the user because other user can see if he's taking it correctly, so I use Moment JS to manipulate the datetime and save the notification and create a node for that user in firebase with UNIX time.
LET'S FINALLY GO TO THE PROBLEM.
When saving a date I check if this date is DST, if it is I add +3 hours to it, if it's not I add +2. I need to add this because when I wrap the isoString in the Moment() function it gives me -3 hours or -2 hours (Haven't searched for this, but I think Moment uses USA time).
This works fine if I'm saving dates inside DST times if I'm in DST time, if in some case I'm not on DST and save a notification for a DST time day it saves with +2 hours.
AN EXAMPLE
The DST time will shift to in DST on October 15. If I need to save 30 notifications, one per day everyday as 12AM, starting at October 1 up to October 30. From day 1 to day 15 the dates will be right, from day 16 to 30 they'll be with +2 hours.
Here's the basic code I use:
// THIS'LL SET MY DATEPICKER TO THE DATE/HOUR I'M IN.
minDate: any = Moment().isDST ? Moment().subtract(3, 'h').toDate().toISOString() : Moment().subtract(2, 'h').toDate().toISOString();
// THIS'LL CONVERT THE SELECTED DATE TO A UNIX TIME IN WICH I'LL USE TO SAVE THE NOTIFICATION AND THE MEDICATION DATA ON FIREBASE
unixConverted = Moment(this.minDate).isDST ? Moment(this.minDate).add(3, 'h').unix() : Moment(this.minDate).add(2, 'h').unix();
What is strange is that using Moment().unix() alone it give me the right time I'm in, if I use Moment(this.minDate).unix() it gives me -2 or -3 hours of the hour I selected.
So if it's in DST (in which I've set my clock to -1 hour) I add 3, if not I add 2.
So how is the proper way to manipulate this DST shift?
Is there a better way to do this than using DST?
Am I right using this logic or is this much more complex than what I think?
Ok so i've found a better way without using .isDST() method.
Simple use Moment().add(Moment().utcOffset(), 'm'), this'll get the current moment time and add the offset in minutes.
The .add() and .subract() methods makes Moment return the UTC time.
The utcOffset() returns a positive or negative number of minutes (representing hours) from UTC, like -60 or 180. So i'll get the correct respecting the time shift.
Worked like a charm for me.
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);
I have a user inputted date which I convert to a moment
var newDate = moment('01/02/2015');
What I need to do is get the previous friday relative to whatever date is passed in. How can I accomplish this?
I thought about doing something like this:
moment('01/02/2015').add('-1', 'week').day(5);
but wonder how reliable it would be.
newDate.day(-2);
It's that easy. :)
day() sets the day of the week relative to the moment object it is working on.
moment().day(0) always goes back to the beginning of the week. moment().day(-2)goes back two days further than the beginning of the week, i.e., last Friday.
Note: this will return to the Friday of the previous week even if newDate is on Friday or Saturday. To avoid this behavior, use this:
newDate.day(newDate.day() >= 5 ? 5 :-2);
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 ;-)