JavaScript - get the first day of the week from current date
Asked Answered
Y

21

238

I need the fastest way to get the first day of the week. For example: today is the 11th of November, and a Thursday; and I want the first day of this week, which is the 8th of November, and a Monday. I need the fastest method for MongoDB map function, any ideas?

Yalonda answered 11/11, 2010 at 16:6 Comment(4)
If every little bit of speed is crucial, you may want to performance test my answer. I'm getting a little better performance with mine in browsers (except for IE, which favors CMS). Of course, you would need to test it with MongoDB. When the function gets passed a date that is Monday, it should be even faster, since it just returns the unmodified original date.Lemmon
I got the same problem and because javascript date object have a lot of bugs I'm using now datejs.com (here code.google.com/p/datejs), a library that correct the miss behavior of the native date.Eupepsia
The question title asks for the first day of the week while the question description asks for the date of the last Monday. These are actually two different questions. Check my answer that solves them both in a correct manner.Mobility
To set a Date to Monday at the start of the week is simply date.setDate(date.getDate() - (date.getDay() || 7) + 1).Bierman
F
425

Using the getDay method of Date objects, you can know the number of day of the week (being 0=Sunday, 1=Monday, etc).

You can then subtract that number of days plus one, for example:

function getMonday(d) {
  d = new Date(d);
  var day = d.getDay(),
    diff = d.getDate() - day + (day == 0 ? -6 : 1); // adjust when day is sunday
  return new Date(d.setDate(diff));
}

console.log( getMonday(new Date()) ); // e.g. Mon Nov 08 2010
Factual answered 11/11, 2010 at 16:13 Comment(12)
Does this function has a bug? - if the date in question is Thursday the 2nd, day = 4, diff = 2 - 4 + 1 = -1, and the result of setDate will be 'the day before the last day of the previous month' (see this).Yippie
@Yippie what do you mean? For May 2 the function returns April 29, which is correct.Wheatworm
If Sunday is the first day of the week, use: diff = d.getDate() - day;Falcon
Using BeanShell the following code worked for me: Date date = new Date(); int dayIndex = date.getDay(); // 0 = Sunday, 1 = Monday ... int diff = dayIndex - (dayIndex == 0? -6 : 1); date.setDate(date.getDate()-diff); SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd"); String formattedDate = df.format(date); vars.put("dateOfLastMonday",formattedDate);Airhead
It didn't work for me when the previous Monday of the date belongs to another month for example d = '2016-01-1' it returns "monday": "2015-12-27T06:00:00.000Z" which is wrong because it must return 2015-12-28Endoderm
Thanks for the code @SMS . I made a little twist for getting exactly 0 hours of the first day of week. d.setHours(0); d.setMinutes(0); d.setSeconds(0);Ioneionesco
You may want to check my answer which takes the first day of week as second parameter.Mobility
upvoted how would get 00:00:00 in utc of this mondayGod
by the way, d.setDate is mutable, it changes the "d" itselfClaymore
function getMonday(d) { d = new Date(d); var day = d.getDay(), diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday return new Date(d.setDate(diff)); } seems better, setDate return a Date?Olfe
@Claymore hence the clone at the begining. But the last new Date is useless: d.setDate(diff); return d; is enoughArm
@Claymore Date.prototype.setDate is not mutable. When called it mutates the Date it is called upon)Sleuth
L
71

Not sure how it compares for performance, but this works.

var today = new Date();
var day = today.getDay() || 7; // Get current day number, converting Sun. to 7
if (day !== 1) // Only manipulate the date if it isn't Mon.
  today.setHours(-24 * (day - 1)); // Set the hours to day number minus 1
//   multiplied by negative 24
console.log(today); // will be Monday

Or as a function:

# modifies _date_
function setToMonday( date ) {
    var day = date.getDay() || 7;  
    if( day !== 1 ) 
        date.setHours(-24 * (day - 1)); 
    return date;
}

setToMonday(new Date());
Lemmon answered 11/11, 2010 at 16:19 Comment(5)
This should have been the answer, its the only one that answers the question asked. The others are buggy or refer you to third party libraries.Jewett
Cool it works for me! By making some adjustments I cool get both, Monday and Friday of the week from a given date!Endoderm
This is great except this function should be called "setToMonday" as it modifies the date object passed in. getMonday, would return a new Date that is the monday based on the date passed in. A subtle difference, but one that caught me after using this function. Easiest fix is to put date = new Date(date); as the first line in the getMonday function.Sympetalous
This is awesome. A getSunday method is even easier! Thanks a bunch!Wescott
This answer is wrong because not all days have 24h because of daytime savings. It may either change the hour of your date unexpectedly or even return the wrong day at certain occasions.Mobility
M
25

CMS's answer is correct but assumes that Monday is the first day of the week.
Chandler Zwolle's answer is correct but fiddles with the Date prototype.
Other answers that add/subtract hours/minutes/seconds/milliseconds are wrong because not all days have 24 hours.

The function below is correct and takes a date as first parameter and the desired first day of the week as second parameter (0 for Sunday, 1 for Monday, etc.). Note: the hour, minutes and seconds are set to 0 to have the beginning of the day.

function firstDayOfWeek(dateObject, firstDayOfWeekIndex) {

    const dayOfWeek = dateObject.getDay(),
        firstDayOfWeek = new Date(dateObject),
        diff = dayOfWeek >= firstDayOfWeekIndex ?
            dayOfWeek - firstDayOfWeekIndex :
            6 - dayOfWeek

    firstDayOfWeek.setDate(dateObject.getDate() - diff)
    firstDayOfWeek.setHours(0,0,0,0)

    return firstDayOfWeek
}

// August 18th was a Saturday
let lastMonday = firstDayOfWeek(new Date('August 18, 2018 03:24:00'), 1)

// outputs something like "Mon Aug 13 2018 00:00:00 GMT+0200"
// (may vary according to your time zone)
document.write(lastMonday)
Mobility answered 19/8, 2018 at 14:5 Comment(2)
For those who are searching for lastDayofTheWeek jsfiddle.net/codeandcloud/5ct8odqrParvenu
That should be the correct answer. Even the hours has been reset!Aiello
A
17

📆 First / Last Day of The Week

To get the upcoming first day of the week, you can use something like so:

function getUpcomingSunday() {
  const date = new Date();
  const today = date.getDate();
  const currentDay = date.getDay();
  const newDate = date.setDate(today - currentDay + 7);
  return new Date(newDate);
}

console.log(getUpcomingSunday());

Or to get the latest first day:

function getLastSunday() {
  const date = new Date();
  const today = date.getDate();
  const currentDay = date.getDay();
  const newDate = date.setDate(today - (currentDay || 7));
  return new Date(newDate);
}

console.log(getLastSunday());

* Depending on your time zone, the beginning of the week doesn't has to start on Sunday, it can start on Friday, Saturday, Monday or any other day your machine is set to. Those methods will account for that.

* You can also format it using toISOString method like so: getLastSunday().toISOString()

Alyse answered 15/2, 2020 at 20:57 Comment(2)
"Those methods will account for that." my result yields a Sunday, and the first day of the week here is Monday 🤔.Unclothe
@Me Thanks for the feedback. Can you check the first day of the week setting on your machine? It should work as described. LMKAlyse
G
14

Check out Date.js

Date.today().previous().monday()
Genitals answered 11/11, 2010 at 16:9 Comment(5)
or maybe Date.parse('last monday');Outwear
I need it for MongoDB database. So i can't reference date.js, but thank you for your code snippet.Yalonda
Ah, I wasn't aware you could execute JS directly in MongoDB. That's pretty slick. Had assumed you were using the JS to prepare the query data.Genitals
Like jQuery, not interested in pulling down an entire library (no matter how small) to get access to one simple function.Cartography
Not a good solution, because there are countries, their first day of the week is sunday.Ting
P
10
var dt = new Date(); // current date of week
var currentWeekDay = dt.getDay();
var lessDays = currentWeekDay == 0 ? 6 : currentWeekDay - 1;
var wkStart = new Date(new Date(dt).setDate(dt.getDate() - lessDays));
var wkEnd = new Date(new Date(wkStart).setDate(wkStart.getDate() + 6));

This will work well.

Parabolic answered 3/5, 2017 at 5:29 Comment(0)
G
5

I'm using this

function get_next_week_start() {
   var now = new Date();
   var next_week_start = new Date(now.getFullYear(), now.getMonth(), now.getDate()+(8 - now.getDay()));
   return next_week_start;
}
Gizzard answered 24/7, 2014 at 9:3 Comment(0)
M
5

Returns Monday 00am to Monday 00am.

const now = new Date()
const startOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay() + 1)
const endOfWeek = new Date(now.getFullYear(), now.getMonth(), startOfWeek.getDate() + 7)
Myrna answered 22/6, 2021 at 13:58 Comment(3)
that is the actual nice solution: d.setDate(d.getDate() - d.getDay + whatever) A one-liner Thank youPryer
That is also a good one! However you're mutating the d variable, use with care since it might produce wrong results depending on the context (i.e. repeating this code, handling different timezones, multi-threads).Myrna
yeah, functional is usually better. I only use this on stack variables. Thanks for the warning thoughPryer
S
3

This function uses the current millisecond time to subtract the current week, and then subtracts one more week if the current date is on a monday (javascript counts from sunday).

function getMonday(fromDate) {
    // length of one day i milliseconds
  var dayLength = 24 * 60 * 60 * 1000;

  // Get the current date (without time)
    var currentDate = new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate());

  // Get the current date's millisecond for this week
  var currentWeekDayMillisecond = ((currentDate.getDay()) * dayLength);

  // subtract the current date with the current date's millisecond for this week
  var monday = new Date(currentDate.getTime() - currentWeekDayMillisecond + dayLength);

  if (monday > currentDate) {
    // It is sunday, so we need to go back further
    monday = new Date(monday.getTime() - (dayLength * 7));
  }

  return monday;
}

I have tested it when week spans over from one month to another (and also years), and it seems to work properly.

Stilla answered 19/5, 2016 at 21:13 Comment(0)
P
3

Good evening,

I prefer to just have a simple extension method:

Date.prototype.startOfWeek = function (pStartOfWeek) {
    var mDifference = this.getDay() - pStartOfWeek;

    if (mDifference < 0) {
        mDifference += 7;
    }

    return new Date(this.addDays(mDifference * -1));
}

You'll notice this actually utilizes another extension method that I use:

Date.prototype.addDays = function (pDays) {
    var mDate = new Date(this.valueOf());
    mDate.setDate(mDate.getDate() + pDays);
    return mDate;
};

Now, if your weeks start on Sunday, pass in a "0" for the pStartOfWeek parameter, like so:

var mThisSunday = new Date().startOfWeek(0);

Similarly, if your weeks start on Monday, pass in a "1" for the pStartOfWeek parameter:

var mThisMonday = new Date().startOfWeek(1);

Regards,

Paniagua answered 3/6, 2016 at 19:9 Comment(0)
T
3

Simple solution for getting the first day of the week.

With this solution, it is possible to set an arbitrary start of week (e.g. Sunday = 0, Monday = 1, Tuesday = 2, etc.).

function getBeginOfWeek(date = new Date(), startOfWeek = 1) {
    const result = new Date(date);
    while (result.getDay() !== startOfWeek) {
        result.setDate(result.getDate() - 1);
    }
    return result;
}
  • The solution correctly wraps on months (due to Date.setDate() being used)
  • For startOfWeek, the same constant numbers as in Date.getDay() can be used
Toomin answered 2/2, 2022 at 14:40 Comment(0)
S
2

a more generalized version of this... this will give you any day in the current week based on what day you specify.

//returns the relative day in the week 0 = Sunday, 1 = Monday ... 6 = Saturday
function getRelativeDayInWeek(d,dy) {
  d = new Date(d);
  var day = d.getDay(),
      diff = d.getDate() - day + (day == 0 ? -6:dy); // adjust when day is sunday
  return new Date(d.setDate(diff));
}

var monday = getRelativeDayInWeek(new Date(),1);
var friday = getRelativeDayInWeek(new Date(),5);

console.log(monday);
console.log(friday);
Slr answered 14/7, 2020 at 16:11 Comment(1)
@mate.gvo Care to explain what is not working for you? It works fine for me.Herl
S
1

setDate() has issues with month boundaries that are noted in comments above. A clean workaround is to find the date difference using epoch timestamps rather than the (surprisingly counterintuitive) methods on the Date object. I.e.

function getPreviousMonday(fromDate) {
    var dayMillisecs = 24 * 60 * 60 * 1000;

    // Get Date object truncated to date.
    var d = new Date(new Date(fromDate || Date()).toISOString().slice(0, 10));

    // If today is Sunday (day 0) subtract an extra 7 days.
    var dayDiff = d.getDay() === 0 ? 7 : 0;

    // Get date diff in millisecs to avoid setDate() bugs with month boundaries.
    var mondayMillisecs = d.getTime() - (d.getDay() + dayDiff) * dayMillisecs;

    // Return date as YYYY-MM-DD string.
    return new Date(mondayMillisecs).toISOString().slice(0, 10);
}
Sickness answered 2/6, 2016 at 23:51 Comment(0)
D
1

Here is my solution:

function getWeekDates(){
    var day_milliseconds = 24*60*60*1000;
    var dates = [];
    var current_date = new Date();
    var monday = new Date(current_date.getTime()-(current_date.getDay()-1)*day_milliseconds);
    var sunday = new Date(monday.getTime()+6*day_milliseconds);
    dates.push(monday);
    for(var i = 1; i < 6; i++){
        dates.push(new Date(monday.getTime()+i*day_milliseconds));
    }
    dates.push(sunday);
    return dates;
}

Now you can pick date by returned array index.

Dali answered 28/7, 2016 at 12:58 Comment(0)
R
1

An example of the mathematically only calculation, without any Date functions.

const date = new Date();
const ts = +date;

const mondayTS = ts - ts % (60 * 60 * 24 * (7-4) * 1000);

const monday = new Date(mondayTS);
console.log(monday.toISOString(), 'Day:', monday.getDay());

const formatTS = v => new Date(v).toISOString();
const adjust = (v, d = 1) => v - v % (d * 1000);

const d = new Date('2020-04-22T21:48:17.468Z');
const ts = +d; // 1587592097468

const test = v => console.log(formatTS(adjust(ts, v)));

test();                     // 2020-04-22T21:48:17.000Z
test(60);                   // 2020-04-22T21:48:00.000Z
test(60 * 60);              // 2020-04-22T21:00:00.000Z
test(60 * 60 * 24);         // 2020-04-22T00:00:00.000Z
test(60 * 60 * 24 * (7-4)); // 2020-04-20T00:00:00.000Z, monday

// So, what does `(7-4)` mean?
// 7 - days number in the week
// 4 - shifting for the weekday number of the first second of the 1970 year, the first time stamp second.
//     new Date(0)          ---> 1970-01-01T00:00:00.000Z
//     new Date(0).getDay() ---> 4
Radiator answered 22/4, 2020 at 22:16 Comment(1)
This answer assumes that the date is in a specific part of the week. It might give you the last Thursday! Instead of %-ing to a half-week offset the calculation: ts=+ts+60*60*24*1000 * 3; return new Date((ts - ts % (60 * 60 * 24 * 7 * 1000))-60*60*24*1000 * 3)Materse
D
1

It is important to discern between local time and UTC. I wanted to find the start of the week in UTC, so I used the following function.

function start_of_week_utc(date, start_day = 1) {

// Returns the start of the week containing a 'date'. Monday 00:00 UTC is
// considered to be the boundary between adjacent weeks, unless 'start_day' is
// specified. A Date object is returned.

    date = new Date(date);
    const day_of_month = date.getUTCDate();
    const day_of_week = date.getUTCDay();
    const difference_in_days = (
        day_of_week >= start_day
        ? day_of_week - start_day
        : day_of_week - start_day + 7
    );
    date.setUTCDate(day_of_month - difference_in_days);
    date.setUTCHours(0);
    date.setUTCMinutes(0);
    date.setUTCSeconds(0);
    date.setUTCMilliseconds(0);
    return date;
}

To find the start of the week in a given timezone, first add the timezone offset to the input date and then subtract it from the output date.

const local_start_of_week = new Date(
    start_of_week_utc(
        date.getTime() + timezone_offset_ms
    ).getTime() - timezone_offset_ms
);
Done answered 11/7, 2022 at 1:26 Comment(2)
For the specific timezone part, is there any reason you're first adding and then subtracting the timezone offset? Why not just get the start of the week in UTC first, and then just add the timezone offset to that UTC start of the week (to get the start of the week in the desired timezone)?Phenothiazine
Because the result might then be wrong by a week if the date is near the week boundary. Compare the approaches using the date 2022-08-21T23:30:00.000Z and a timezone offset of 1 hour.Done
G
1

Accepted answer won't work for anyone who runs the code in UTC-XX:XX timezone.

Here is code which will work regardless of timezone for date only. This won't work if you provide time too. Only provide date or parse date and provide it as input. I have mentioned different test cases at start of the code.

function getDateForTheMonday(dateString) {
  var orignalDate = new Date(dateString)
  var modifiedDate = new Date(dateString)
  var day = modifiedDate.getDay()
  diff = modifiedDate.getDate() - day + (day == 0 ? -6:1);// adjust when day is sunday
  modifiedDate.setDate(diff)

  var diffInDate = orignalDate.getDate() - modifiedDate.getDate()
  if(diffInDate == 6) {
    diff = diff + 7
    modifiedDate.setDate(diff)
  }
  console.log("Given Date : " + orignalDate.toUTCString())
  console.log("Modified date for Monday : " + modifiedDate)
}

getDateForTheMonday("2022-08-01") // Jul month with 31 Days
getDateForTheMonday("2022-07-01") // June month with 30 days
getDateForTheMonday("2022-03-01") // Non leap year February
getDateForTheMonday("2020-03-01") // Leap year February
getDateForTheMonday("2022-01-01") // First day of the year
getDateForTheMonday("2021-12-31") // Last day of the year
Got answered 23/8, 2022 at 18:37 Comment(1)
If you need UTC dates, you just need to use UTC counterparts of Date objects. For eg, getUTCDay() instead of getDay(). See stackoverflow.com/a/72932929Trierarch
I
0

I use this:

let current_date = new Date();
let days_to_monday = 1 - current_date.getDay();
monday_date = current_date.addDays(days_to_monday);

// https://mcmap.net/q/45104/-how-to-add-days-to-date
Date.prototype.addDays = function(days) {
    var date = new Date(this.valueOf());
    date.setDate(date.getDate() + days);
    return date;
}

It works fine.

Intermix answered 11/8, 2021 at 20:48 Comment(1)
Consider return new Date(this.getFullYear(), this.getMonth(), this.getDate() + days) which zeros the time, which may or may not be desired. If not, copy over hours, minutes, seconds and milliseconds too.Bierman
F
0

Extending answer from @Christian C. Salvadó and information from @Ayyash (object is mutable) and @Awi and @Louis Ameline (set hours to 00:00:00)

The function can be like this

function getMonday(d) {
  var day = d.getDay(),
      diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
  d.setDate(diff);
  d.setHours(0,0,0,0); // set hours to 00:00:00

  return d; // object is mutable no need to recreate object
}

getMonday(new Date())
Foreskin answered 1/2, 2023 at 2:43 Comment(0)
C
0

This one-line solution works fine:

var date = new Date();

var weekStart = new Date(new Date(date).setDate(date.getDate() - (date.getDay() == 0 ? 6 : date.getDay() - 1)));
var weekEnd = new Date(new Date(weekStart).setDate(weekStart.getDate() + 6));

console.log('Week start: ' + weekStart);
console.log('Week end: ' + weekEnd);
Circumflex answered 11/9, 2023 at 8:34 Comment(0)
N
-4

Check out: moment.js

Example:

moment().day(-7); // last Sunday (0 - 7)
moment().day(7); // next Sunday (0 + 7)
moment().day(10); // next Wednesday (3 + 7)
moment().day(24); // 3 Wednesdays from now (3 + 7 + 7 + 7)

Bonus: works with node.js too

Nikolenikoletta answered 17/3, 2014 at 6:18 Comment(3)
That's not an answer to OP's question though. He has a date, say 08/07/14 (d/m/y). He wants to get the first day of this week (for my locale this would be the Monday that has just passed, or yesterday) An answer to his question with moment would be moment().startOf('week')Coltish
Note that moment().startOf("week") might give the date of the previous Sunday, depending on locale settings. In that case, use moment().startOf('isoWeek') instead: runkit.com/embed/wdpi4bjwh6rtBurglary
PS Docs on startOf(): momentjs.com/docs/#/manipulating/start-ofBurglary

© 2022 - 2024 — McMap. All rights reserved.