Getting the last Monday - javascript

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);

Related

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.

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

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.

Get the most recently occurring Sunday

I need to display the current week in a calendar view, starting from Sunday.
What's the safest way to determine "last sunday" in Javascript?
I was calculating it using the following code:
Date.prototype.addDays = function(n) {
return new Date(this.getTime() + (24*60*60*1000)*n);
}
var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
var lastSunday = today.addDays(0-today.getDay());
This code makes the assumption that every day consists of twenty four hours. This is correct, EXCEPT if it's a daylight savings crossover day, in which case the day could be twenty-three or twenty-five hours.
This week, In Sydney, Australia, we set our clocks forward an hour. As a result, my code calculates lastSunday as 23:00 on Saturday.
So what IS the safest and most efficient way to determine last Sunday?
To safely add exactly one day, use:
d.setDate(d.getDate() + 1);
which is daylight saving safe. To set a date object to the last Sunday:
function setToLastSunday(d) {
return d.setDate(d.getDate() - d.getDay());
}
Or to return a new Date object for last Sunday:
function getLastSunday(d) {
var t = new Date(d);
t.setDate(t.getDate() - t.getDay());
return t;
}
Edit
The original answer had an incorrect version adding time, that does add one day but not how the OP wants.
Try this jsfiddle
It uses only built in date methods
var now = new Date();
var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
var lastSunday = new Date(today.setDate(today.getDate()-today.getDay()));
using date-fn library: previousSunday(date)
const now = new Date(); // the date to start counting from
previousSunday(now);
Docs: https://date-fns.org/v2.25.0/docs/previousSunday

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