Certain timezones start the week on a Monday rather than Sunday, f.e. Germany. I expected Moment.tz("Europe/Berlin").startOf("week")
to return Monday but instead it returns Sunday. Any way to workaround this?
Moment.tz("Europe/Berlin").startOf("week") returning Sunday instead of Monday
64 views Asked by user17443811 At
3
There are 3 answers
4
On
Updated Answer:
You can use Intl.Locale.prototype.getWeekInfo()
, but Firefox doesn't support it at all.
const fallBackStartOfWeek = {
'de-DE': 1,
'en-US': 7
};
const getFallbackStartOfWeek = (tz) =>
Object.keys(fallBackStartOfWeek).includes(tz)
? fallBackStartOfWeek[tz] : 7; // fallback to sunday;
const getStartOfTheWeek = (date, tz) => {
const locale = new Intl.Locale(tz);
let firstDay = -1;
if (locale.getWeekInfo) { // safari
firstDay = locale.getWeekInfo().firstDay;
} else if (locale.weekInfo) { // chrome, edge, opera
firstDay = locale.weekInfo.firstDay;
} else { // firefox. not implemented yet
firstDay = getFallbackStartOfWeek(tz);
}
return moment(date).day(firstDay).toString();
}
const germanStartOfWeek = getStartOfTheWeek('2023-11-07', 'de-DE');
const usStartOfWeek = getStartOfTheWeek('2023-11-07', 'en-US');
console.log({
german: germanStartOfWeek,
us: usStartOfWeek
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.43/moment-timezone-with-data.min.js"></script>
Browser Compatibility: Intl: Locale: getWeekInfo
Old Answer:
You can use getDay('Monday')
or getDay(0)
to get Monday on all the timezone locale.
const mondayBerlin = moment('2023-11-07').tz('Europe/Berlin').day('Monday');
console.log({
date: moment(mondayBerlin).format('yyyy-MM-DD'),
day: moment(mondayBerlin).format('dddd')
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.43/moment-timezone-with-data.min.js"></script>
0
On
The starting day of the week is an aspect of locale, not time zone. They are independent concepts. You can use one or the other, or both.
// start of the week in your local time zone and the default locale
const m1 = moment().startOf('week');
// start of the week in your local time zone, using a German locale
const m2 = moment().locale('de').startOf('week');
// start of the week in Germany's time zone, using the default locale
const m3 = moment.tz('Europe/Berlin').startOf('week');
// start of the week in Germany's time zone, using a German locale
const m4 = moment.tz('Europe/Berlin').locale('de').startOf('week');
console.log('m1:', m1.toString());
console.log('m2:', m2.toString());
console.log('m3:', m3.toString());
console.log('m4:', m4.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.43/moment-timezone-with-data-10-year-range.min.js"></script>
I think you are expecting the behavior of the fourth example above, though you are using the third.
Also keep in mind that Moment.js is generally considered obsolete, and should only be used on legacy projects.
Start of week is dependent on locale (see link below to docs and an example).
See here and here