Starting the week on Monday with isoWeekday()
Asked Answered
H

8

154

I'm creating a calendar where I print out weeks in a tabular format. One requirement is that I be able to start the weeks either on Monday or Sunday, as per some user option. I'm having a hard time using moment's isoWeekday method.

// Start of some date range. Can be any day of the week.
var startOfPeriod = moment("2013-06-23T00:00:00"),

    // We begin on the start of the first week.
    // Mon Tues Wed Thur Fri Sat Sun
    // 20  21   22  23   24  25  26
    begin = moment(startOfPeriod).isoWeekday(1); // will pull from user setting

console.log(begin.isoWeekday()); // 1 - all good

// Let's get the beginning of this first week, respecting the isoWeekday
begin.startOf('week');

console.log(begin.isoWeekday()); // 7 - what happened ???

// Get column headers
for (var i=0; i<7; i++) {
    console.log(begin.format('ddd')); // I want Monday first!
    begin.add('d', 1);
}

jsFiddle

EDIT I misunderstood what isoWeekday was actually doing. I thought it set the "which day of the week is the first day of the week" variable (that doesn't exist). What it actually does is simply changes the day of the week, just like moment.weekday(), but uses a 1-7 range instead of the 0-6.

Hippopotamus answered 18/9, 2013 at 14:56 Comment(0)
P
315

You just need to replace begin.startOf('isoWeek'); with begin.startOf('week');.

Pubis answered 18/9, 2013 at 15:8 Comment(5)
startOf('week') depends on the current locale where Sunday obviously marks the start of the week in your case. startOf('iweek') will get the ISO start of the week, which is Monday. But you're right, I didn't find any documentation on the official site ...Soilure
Current version of moment.js is using isoweek.Hippopotamus
Edited according to @savinger's comment and the current docs :)Lamond
isoWeek, with a capital W, in the latest versionZebedee
Documented here: Start of TimeTintype
L
26

This way you can set the initial day of the week.

moment.locale('en', {
    week: {
        dow: 6
    }
});
moment.locale('en');

Make sure to use it with moment().weekday(1); instead of moment.isoWeekday(1)

Lied answered 24/4, 2018 at 16:7 Comment(1)
Just update, that new release requires doy (First day of the year) as well. It worked for me, thanks.Unction
S
17

Call startOf before isoWeekday.

var begin = moment(date).startOf('week').isoWeekday(1);

Working demo

Sheppard answered 18/9, 2013 at 15:14 Comment(2)
This does not work properly. For today's date, 2016-09-05 it returns 2016-08-29 as a begin date of the week which is not true, because today is Monday (iso week). the proper answer is already accepted.Badr
Don't understand why is is so popular because it is obviously wrong. startOf('week') returns Sunday (of the past Week) and setting it then to Monday sets it one week to early.Courtesy
R
2

thought I would add this for any future peeps. It will always make sure that its monday if needed, can also be used to always ensure sunday. For me I always need monday, but local is dependant on the machine being used, and this is an easy fix:

var begin = moment().isoWeekday(1).startOf('week');
var begin2 = moment().startOf('week');
// could check to see if day 1 = Sunday  then add 1 day
// my mac on bst still treats day 1 as sunday    

var firstDay = moment().startOf('week').format('dddd') === 'Sunday' ?     
moment().startOf('week').add('d',1).format('dddd DD-MM-YYYY') : 
moment().startOf('week').format('dddd DD-MM-YYYY');

document.body.innerHTML = '<b>could be monday or sunday depending on client: </b><br />' + 
begin.format('dddd DD-MM-YYYY') + 
'<br /><br /> <b>should be monday:</b> <br>' + firstDay + 
'<br><br> <b>could also be sunday or monday </b><br> ' + 
begin2.format('dddd DD-MM-YYYY');
Robalo answered 18/8, 2015 at 14:43 Comment(1)
possible shortcut moment().isoWeekday(1).startOf('isoweek').format('dddd DD MM YYYY')Robalo
J
2

Here is a more generic solution for any given weekday. Working demo on jsfiddle

var myIsoWeekDay = 2; // say our weeks start on tuesday, for monday you would type 1, etc.

var startOfPeriod = moment("2013-06-23T00:00:00"),

// how many days do we have to substract?
var daysToSubtract = moment(startOfPeriod).isoWeekday() >= myIsoWeekDay ?
    moment(startOfPeriod).isoWeekday() - myIsoWeekDay :
    7 + moment(startOfPeriod).isoWeekday() - myIsoWeekDay;

// subtract days from start of period
var begin = moment(startOfPeriod).subtract('d', daysToSubtract);
Jacintajacinth answered 20/4, 2017 at 12:24 Comment(0)
H
1

This worked for me

var begin = moment(date).isoWeekday(1).startOf('isoWeek');
Herbartian answered 28/7, 2023 at 15:0 Comment(0)
S
0

<!-- Starting Date From Monday -->
var moment= moment.js;
<!-- Javascript Code -->

var begin = moment().startOf('week').add('days', 1)


<!--  React JS  Code -->

var begin = moment().startOf('week').add(2, 'days');
Sallyanne answered 18/7, 2023 at 10:31 Comment(0)
A
-2

For those who want isoWeek to be the default you can modify moment's behaviour as such:

const moment = require('moment');
const proto = Object.getPrototypeOf(moment());

const {startOf, endOf} = proto;
proto.startOf = function(period) {
  if (period === 'week') {
    period = 'isoWeek';
  }
  return startOf.call(this, period);
};
proto.endOf = function(period) {
  if (period === 'week') {
    period = 'isoWeek';
  }
  return endOf.call(this, period);
};

Now you can simply use someDate.startOf('week') without worrying you'll get sunday or having to think about whether to use isoweek or isoWeek etc.

Plus you can store this in a variable like const period = 'week' and use it safely in subtract() or add() operations, e.g. moment().subtract(1, period).startOf(period);. This won't work with period being isoWeek.

Astatine answered 17/6, 2018 at 23:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.