How to disable month end Days like 30,31, 28(feb), 29 feb(leep year)? in js calender
To check if a date should be included, create a Date object from the components, then check if it contains the expected day. If the date doesn't exist, for example 2010-02-31, it will become the corresponding date in the next month, i.e. 2010-03-03.
Example:
function checkIfDayExists(year, month, day) {
var d = new Date(year, month - 1, day);
return d.getDay == day;
}
Related
I'm trying to calculate a date based on another date by adding a certain period of time. Let's say if I want to add 3 months to a date, then the new date should be one day before the date after 3 months. Taking that example, below is the code that I came closest to for achieving what I want to do:
new Date(
date
.setMonth(date.getMonth() + 3)
.setDate(date.getDate() - 1)
)
But this returns an error: TypeError: date.setMonth(...).setDate is not a function. I think the chaining of methods is not working, so I'll probably have to setDate in the next statement. Is there a way to do this in a single statement of code?
Is there a way to set date and month on a date object in a single statement?
Yes. The following sets the month to January and the day to the first on one statement:
let d = new Date();
d.setMonth(0, 1);
…if I want to add 3 months to a date, then the new date should be one day before the date after 3 months
No, you can't do that in one statement because adding a month needs to consider the number of days in the month. E.g. adding one month to 31 Jan 2020 results in
31 Feb, and since there were only 29 days in Feb 2020, the date is set to 2 Mar 2020. Similarly, adding 1 month to 31 May gives 31 Jun which rolls over to 1 Jul. So you need to add months first (see Adding months to a Date in JavaScript), then subtract one day (see Add days to JavaScript Date).
You could extend the Date Object and create your own methods which are chainable.
class MyDate extends Date {
constructor() {
super(...arguments)
}
changeMonth(amount) {
return new MyDate(this.setMonth(this.getMonth() + amount));
}
changeDate(amount) {
return new MyDate(this.setDate(this.getDate() + amount));
}
};
const date = new MyDate();
console.log("Original:", date);
console.log("Changed :", date.changeMonth(3).changeDate(-5));
You could so something like
newDate = new Date(newDate.getFullYear(), newDate.getMonth() + 3, endDate.getDate() -1)
Turns out there is a very simple solution. The setMonth() method allows us to pass an optional dayValue parameter (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setMonth). Using which, the code simply becomes:
new Date(
date.setMonth(
date.getMonth() + 3,
date.getDate() - 1
)
)
I am looking to do something quite complex and I've been using moment.js or countdown.js to try and solve this, but I think my requirements are too complex? I may be wrong. Here is the criteria...
I need to be able to have the following achievable without having to change the dates manually each year, only add it once and have many countdowns on one page.
Find current date
Find current year
Find current month
Find day within week of month that applies
¬ 3rd Sunday or 2nd Saturday
Convert to JS and output as html and run countdown
When past date - reset for following year
Pretty mental. So for example if an event is always on the 3rd Sunday of March. The date would not be the same each year.
2016 - Sunday March 19th
2017 - Sunday March 20th
2018 - Sunday March 18th etc.
I hope this is explained well, I realise it may be a total mess though. I managed to get it resetting each year with the date added manually but then someone threw in the spanner of the date being different each year.
var event = new Date();
event = new Date(event.getFullYear() + 1, 3 - 1, 19);
jQuery('#dateEvent').countdown({ until: event });
<div id="dateEvent"></div>
I have edited this answer as I have now put together a solution that works for me. As I believe this isn't simple coding due to the fact it wasn't actually answered 'Please, this is basic coding. pick up a javascript book and learn to code', yeah thanks...
// get the specific day of the week in the month in the year
function getDay(month) {
// Convert date to moment (month 0-11)
var myMonth = moment("April", "MMMM");
// Get first Sunday of the first week of the month
var getDay = myMonth.weekday(0); // sunday is 0
var nWeeks = 3; // 0 is 1st week
// Check if first Sunday is in the given month
if (getDay.month() != month) {
nWeeks++;
}
// Return 3rd Sunday of the month formatted (custom format)
return getDay.add(nWeeks, 'weeks').format("Y-MM-D h:mm:ss");
}
// print out the date as HTML and wrap in span
document.getElementById("day").innerHTML = '<span>' + getDay() + '</span>';
Using
<script src="moment.js"></script>
Hope it helps someone - I'll update when I figure how to + 1 year after it's checked current date and event has passed. I'll look in that JS book.
Please take a look at the below code, I explained in the comment what what does.
You use it by supplying a javascript Date object of any wished start date, and then add as a second value the corresponding year you wish to know the date in.
var date = new Date("2016-03-20");
function getDayInYear(startDate, year) {
// get a moment instance of the start date
var start = moment(startDate);
// collect the moment.js values for the day and month
var day = start.day();
var month = start.month();
// calculate which week in the month the date is.
var nthWeekOfMoth = Math.ceil(start.date() / 7);
// Build up the new moment with a date object, passing the requested year, month and week in it
var newMoment = moment(new Date(year,month,(nthWeekOfMoth * 7)));
// Return the next instance of the requested day from the current newMoment date value.
return newMoment.day(day);
}
var oldMoment = moment(date);
var newMoment2017 = getDayInYear(date,2017);
var newMoment2018 = getDayInYear(date,2018);
console.log(oldMoment.format('YYYY MMMM dddd DD'));
console.log(newMoment2017.format('YYYY MMMM dddd DD'));
console.log(newMoment2018.format('YYYY MMMM dddd DD'));
/** working from today up to 10 years into the future **/
var date = new Date();
var year = date.getFullYear();
for(var i = 0; i < 11; i++) {
console.log(getDayInYear(date, year+i).format('YYYY MMMM dddd DD'));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
I'm using MomentJS and fullcalendar.
I want to get the first Monday of a month.
I tried the following code but it doesn't work.
let date = new Date(year, month, 1)
moment(date).isoWeekday(1)
I believe #xenteros's answer doesn't work for months that begin on a Sunday, because Monday would be the 9th.
Here is a simple fix:
let date = moment().year(y).month(m).date(1).day(8);
if (date.date() > 7)
date.day(-6);
The following code have solved my problem:
let date = moment().set('year', y).set('month', m).set('date', 1).isoWeekday(8)
if(date.date() > 7) { //
date = date.isoWeekday(-6)
}
Here are the steps to get the first monday
Create a day (any day in that specific month)
Get the start of the month, this will return a date
There is two cases for first day, it could be Monday or not Monday
We add 6 days to the first day of the month, if it is Monday, we will get Sunday (same week), else we get a date in the next week that has a Monday (that occure in the same month)
calling startOf('isoWeek') will return the first Monday of that month
let date = new Date(year, month, 1);
const firstMondayOfTheMonth = date
.startOf('month')
.add(6, 'day')
.startOf('isoWeek');
Use moment js.
You can pass as parameter any year and month.
import moment from 'moment';
const startOfMonth = moment().year(2021).month(0).startOf('month').isoWeekday(8);
console.log(startOfMonth.format('dddd DD-MM-YYYY')); // Monday 04-01-2021
Month: 0-11.
I am trying to make a function that can check if a given date is in a specified week ago.
For example, if the input is <1, date object>, then it asks, if the given date is from last week. If the input is <2, date object>, then it asks if the given date is from 2 weeks ago, etc.. (0 is for current week).
Week is Sun-Sat.
this.isOnSpecifiedWeekAgo = function(weeks_ago, inputDate) {
return false;
};
But I don't want to use any libraries, and also I am not sure how to change the week of a date object. Does anyone know how to begin?
Thanks
If you want to find out a date that was a week ago, you can simply subtract 7 days from the current date:
var weekAgo = new Date();
weekAgo.setDate(weekAgo.getDate() - 7);
console.log(weekAgo.toLocaleString());
If you want to find out if a date is in a specific week, you'll need to:
Work out the start date for that week
Work out the end date for that week
See if the date is on or after the start and on or before the end
Since your weeks are Sunday to Saturday, you can get the first day of the week from:
var weekStart = new Date();
weekStart.setDate(weekStart.getDate() - weekStart.getDay());
console.log(weekStart.toLocaleString());
The time should be zeroed, then a new date created for 7 days later. That will be midnight at the start of the following Sunday, which is identical to midnight at the end of the following Saturday. So a function might look like:
function wasWeeksAgo(weeksAgo, date) {
// Create a date
var weekStart = new Date();
// Set time to 00:00:00
weekStart.setHours(0,0,0,0);
// Set to previous Sunday
weekStart.setDate(weekStart.getDate() - weekStart.getDay());
// Set to Sunday on weeksAgo
weekStart.setDate(weekStart.getDate() - 7*weeksAgo)
// Create date for following Saturday at 24:00:00
var weekEnd = new Date(+weekStart);
weekEnd.setDate(weekEnd.getDate() + 7);
// See if date is in that week
return date >= weekStart && date <= weekEnd;
}
// Test if dates in week before today (1 Nov 2016)
// 1 Oct 24 Oct
[new Date(2016,9,1), new Date(2016,9,24)].forEach(function(date) {
console.log(date.toLocaleString() + ' ' + wasWeeksAgo(1, date));
});
Use moment.js http://momentjs.com/docs/#/manipulating/subtract/
We use it a lot and its a great lib.
How can I create a date object which is less than n number of months from another date object? I am looking for something like DateAdd().
Example:
var objCurrentDate = new Date();
Now using objCurrentDate, how can I create a Date object having a date which is six months older than today's date / objCurrentDate?
You can implement very easily an "addMonths" function:
function addMonths(date, months) {
date.setMonth(date.getMonth() + months);
return date;
}
addMonths(new Date(), -6); // six months before now
// Thu Apr 30 2009 01:22:46 GMT-0600
addMonths(new Date(), -12); // a year before now
// Thu Oct 30 2008 01:20:22 GMT-0600
EDIT: As reported by #Brien, there were several problems with the above approach. It wasn't handling correctly the dates where, for example, the original day in the input date is higher than the number of days in the target month.
Another thing I disliked is that the function was mutating the input Date object.
Here's a better implementation handling the edge cases of the end of months and this one doesn't cause any side-effects in the input date supplied:
const getDaysInMonth = (year, month) => new Date(year, month, 0).getDate()
const addMonths = (input, months) => {
const date = new Date(input)
date.setDate(1)
date.setMonth(date.getMonth() + months)
date.setDate(Math.min(input.getDate(), getDaysInMonth(date.getFullYear(), date.getMonth()+1)))
return date
}
console.log(addMonths(new Date('2020-01-31T00:00:00'), -6))
// "2019-07-31T06:00:00.000Z"
console.log(addMonths(new Date('2020-01-31T00:00:00'), 1))
// "2020-02-29T06:00:00.000Z"
console.log(addMonths(new Date('2020-05-31T00:00:00'), -6))
// "2019-11-30T06:00:00.000Z"
console.log(addMonths(new Date('2020-02-29T00:00:00'), -12))
// "2019-02-28T06:00:00.000Z"
Create date object and pass the value of n, where n is number(add/sub) of month.
var dateObj = new Date();
var requiredDate= dateObj.setMonth(dateObj.getMonth() - n);
var oldDate:Date = new Date();
/*
Check and adjust the date -
At the least, make sure that the getDate() returns a
valid date for the calculated month and year.
If it's not valid, change the date as per your needs.
You might want to reset it to 1st day of the month/last day of the month
or change the month and set it to 1st day of next month or whatever.
*/
if(oldDate.getMonth() < n)
oldDate.setFullYear(oldDate.getFullYear() - 1);
oldDate.setMonth((oldDate.getMonth() + n) % 12);
You have to be careful because dates have a lot of edge cases. For example, merely changing the month back by 6 doesn't account for the differing number of days in each month. For example, if you run a function like:
function addMonths(date, months) {
date.setMonth((date.getMonth() + months) % 12);
return date;
}
addMonths(new Date(2020, 7, 31), -6); //months are 0 based so 7 = August
The resulting date to return would be February 31st, 2020. You need to account for differences in the number of days in a month. Other answers have suggested this in various ways, by moving it to the first of the month, or the last of the month, or the first of the next month, etc. Another way to handle it is to keep the date if it is valid, or to move it to the end of the month if it overflows the month's regular dates. You could write this like:
function addMonths(date, months) {
var month = (date.getMonth() + months) % 12;
//create a new Date object that gets the last day of the desired month
var last = new Date(date.getFullYear(), month + 1, 0);
//compare dates and set appropriately
if (date.getDate() <= last.getDate()) {
date.setMonth(month);
}
else {
date.setMonth(month, last.getDate());
}
return date;
}
This at least ensures that the selected day won't "overflow" the month that it is being moved to. Finding the last day of the month with the datePart = 0 method is documented here.
This function still leaves a lot to be desired, as it doesn't add years and you can't subtract more than a year (or you will run into a new issue with negatives being involved). However, fixing those and the other issues you may run into (namely timezones) will be left as an exercise for the reader.