How to check if javascript date is from a specified week ago? - javascript

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.

Related

Getting the last Monday

I'm trying to get 12am of the Monday from the current week, so either today (if the day is Monday) or otherwise look backward for the past Monday.
I've got the following code but not sure where to go from here.
Date date = new Date(); date.setDate(date.getDate()
not sure what to do here
let day = new Date(); // Get current date
day.setDate(day.getDate() - (day.getDay() + 6));
console.log(day.getDay()); // is 1
The general approach will be something like this:
Get the current date. You've already got this with const date = new Date();
Check if the current date is a Monday. date.getDay() will give you a number from 0-6, corresponding to Sunday-Saturday.
If today is not a Monday, change the date to subtract enough days to get us to a Monday. date.getDay() will give you the number of days to get back to Sunday, and then we will need to move back another 6 days to get to the previous Monday: date.setDate(date.getDate() - date.getDay() - 6);
Now that the date is definitely a Monday, change the time to be 12:00am: date.setHours(00, 00, 00);
Putting it all together:
const date = new Date();
if (date.getDay() !== 1) {
date.setDate(date.getDate() - date.getDay() - 6);
}
date.setHours(00,00,00);

Countdown to a single day each year (and find the date of that day in current year)

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>

How to get the first Monday of a month with MomentJS?

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.

Javascript getDay returning incorrect values for April, June, September, November

I'm using this script located here: http://www.javascriptkit.com/script/script2/dyndateselector.shtml
If you try it, and go to any of April, June, September or November, you will notice that the day of the week columns are incorrect. Here's a list of incorrect data (the x starts y stuff is showing the following month.)
Bugged months:
4/April (starts Sunday instead of Friday)
May starts Sunday
6/June (starts Friday instead of Wednesday)
July starts Friday
9/September (starts Saturday instead of Thursday)
October starts Saturday
11/November (starts Thursday instead of Tuesday)
December starts Thursday
You'll notice that every bugged month is starting with the day of the following month, yet all the other months seem to be correct.
I can't find anything on this problem. Anyone able to help? The actual Javascript alone can be found here, and the getDay() method occurs on line 125: http://pastebin.com/0zuBYrzv
I've tested in both Firefox and Chrome.
Here's some very simple code to demonstrate the issue:
<script>
var d = new Date();
d.setMonth(5);
d.setFullYear(2011);
d.setDate(1);
alert(d.getDay());
</script>
This will create an alert with the message "5", meaning Friday (5+1 = 6, Friday is the 6th day of the week,) when in fact Wednesday is the start of the week.
This is actually pretty interesting as i am guessing that tomorrow your original code will work as you want again.
What i think is happening is you are creating a new Date and that will automaticly initialize to today (31th of may).
Then you set the Month to June by which you basically say make it 31th of June. This date doesn't exist so javascript will turn it into 1th of July.
Finally you set the Date but since your month is not anymore what you want it to be the results will be wrong.
Looks like 0 is january and 11 is december.
Apparently JavaScript doesn't like it if I set the month, full year, then day. What I must do is set them all in one function, like so:
<script>
var d = new Date();
d.setFullYear(2011, 5, 1);
alert(d.getDay());
</script>
I think this is a bug in Javascript's Date Object.
Please take a look at the following code.
(I'm using w3school's JSref tool online to see it quickly.)
Please note, the ways used below are told by w3 schools themselves.
Some examples of instantiating a date:
var today = new Date()
var d1 = new Date("October 13, 1975 11:13:00")
var d2 = new Date(79,5,24) (//THIS IS WRONG - unexpected results!!!)
var d3 = new Date(79,5,24,11,33,0)
So please be careful when using this Date object, looks like certain ways of instantiating dates are better than others.
<script type="text/javascript">
function whatDayIsToday(date)
{
var weekday=new Array(7);
weekday[0]="Sunday";
weekday[1]="Monday";
weekday[2]="Tuesday";
weekday[3]="Wednesday";
weekday[4]="Thursday";
weekday[5]="Friday";
weekday[6]="Saturday";
document.write("Today is " + weekday[date.getDay()] + ", <br />");
document.write("the " + date.getDay() + getSuffix(date.getDay()) + " day of the week. <br /><br />")
}
function getSuffix(num)
{
return (num>3)?"th":(num==3)?"rd":(num==2)?"nd":(num==1)?"st":"";
}
//CORRECT
var d3 = new Date("01/01/2011");
whatDayIsToday(d3);
//CORRECT
var d2 = new Date("01/01/2011");
whatDayIsToday(d2);
//DOESN'T WORK
var d5 = new Date("1-1-2011");
whatDayIsToday(d5);
//WRONG
var d4 = new Date("2011", "01", "01");
whatDayIsToday(d4);
//DAY OF WEEK IS WRONG
var d = new Date(2011, 1, 1);
whatDayIsToday(d);
//DAY OF WEEK IS ALSO WRONG
var d0 = new Date(11, 1, 1);
whatDayIsToday(d0);
</script>
outputs (all using some format of 1/1/2011) are:
Today is Saturday,
the 6th day of the week. (CORRECT, January first this year was a saturday)
Today is Saturday,
the 6nd day of the week. (CORRECT)
Today is undefined,
the NaNnd day of the week. (WRONG FORMATTING, DOESN'T WORK - EXPECTED)
Today is Tuesday,
the 2nd day of the week. (WRONG - UNEXPECTED)
Today is Tuesday,
the 2nd day of the week. (WRONG - UNEXPECTED)
Today is Wednesday,
the 3nd day of the week. (WRONG - UNEXPECTED)
Based on the other answers to this question, I'm guessing it has to do with the day I'm on currently (8/26/2011) - this would be my starting new Date() and the days and/or years getting applied in the wrong order.
However, it sure would be nice if this thing worked!
This is the typical wrong approach:
var days = ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"];
var d = new Date();
d.setFullYear(selectYear.options[selectYear.selectedIndex].value);
d.setMonth(selectMonth.options[selectMonth.selectedIndex].value-1);
d.setDate(selectDay.options[selectDay.selectedIndex].value);
alert(days[d.getDay()]);
It will work most of the time. But it will have problems with when current date is 31 and when trying to set date to 31 for when set at a month with less than 31 days.
This is a good way:
var days = ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"];
var d = new Date(0); // solves all problems for existing dates
d.setFullYear(selectYear.options[selectYear.selectedIndex].value);
d.setMonth(selectMonth.options[selectMonth.selectedIndex].value-1);
d.setDate(selectDay.options[selectDay.selectedIndex].value);
if( d.getDate() == selectDay.options[selectDay.selectedIndex].value ) {
alert(days[d.getDay()]);
}
else {
alert("this date doesn't exist"); // date was changed cuz date didn't exist
}
Constructing the date with new Date(0) sets the date to 1 jan, this is good because the date is not 31st and january has 31 days which give us the space we need. It wont fail on the 31st and we don't need to set the datas in any special order. It will always works.
If the user sets month to september (30 days) and date to 31 the data object will hold either 1 oct or 1 sep (depending on which order you set them in). Which is irrelevant because they are both wrong. A simple check if the date is what we set it to will tell us if the date is a existing date, if not we can tell the user this.

Get a date object (six months prior) from another date object

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.

Categories