16

I'd like to display in my i18n-ed app a list of the 7 weekdays:

Sunday, Monday, Tuesday... Saturday

I rely on the Intl global object for formatting date/time but I can't find an easy way to get only the weekday names.

I thought I could add some days to the EPOCH time, to reach the first day of the week, but I'm failing to find a formatter printing just the weekday.

var date = new Date(0);
date.setDate(4 + day);
for (var i = 0; i < 7; i++) {
  var weekday = new Intl.DateTimeFormat(["en"], {
      weekday: "short" // ?? what should I put here
  }).format(date);
  console.log(weekday);
}

Output:

Sunday, January 4, 1970
Monday, January 5, 1970
Tuesday, January 6, 1970
Wednesday, January 7, 1970
Thursday, January 8, 1970
Friday, January 9, 1970
Saturday, January 10, 1970

Desired output:

Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

I also would like to have a shorter version of the days, such as Sun, Mon, Tue....

Alternatively, is there a way to get the weekday strings from Intl? I tried to explore the object via console but I couldn't find them.

gpbl
  • 4,721
  • 5
  • 31
  • 45

7 Answers7

11

I was misled because I was using the Intl polyfill, which does not support yet { weekday: "short" } as option.

Using native Intl implementations works as expected.

gpbl
  • 4,721
  • 5
  • 31
  • 45
  • 1
    Here's some shorter code to return all the weekday names: `for (var day = 5; day <= 11; day++) { new Date(1970, 1 - 1, day).toLocaleString('de', { weekday: 'short' /* or 'long' */ }); }` – Oliver May 18 '17 at 13:11
11

my solution in 2021 with es6

/**
 * Return list of days
 *  localeName : name of local, f.e. en-GB, default es-MX
 * ✅ weekday    : format of weekday short/long (Default)
 */
function daysForLocale(localeName = 'es-MX', weekday = 'long') {
  const {format} = new Intl.DateTimeFormat(localeName, { weekday });
  return [...Array(7).keys()]
    .map((day) => format(new Date(Date.UTC(2021, 5, day))));
}

// ##############################################################
// testing daysForLocale function
// ##############################################################
console.log(daysForLocale());
// ['domingo','lunes',...,'viernes','sábado']
console.log(daysForLocale('en-GB', 'short'));
// ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri','Sat']
console.log(daysForLocale('ja-JP', 'short'));
// ['日', '月', '火','水', '木', '金','土']
Anton Rusak
  • 882
  • 4
  • 18
fitorec
  • 4,257
  • 2
  • 24
  • 18
  • on my local this method works perfectly but somehow when the same unit tests run on jenkins machine index 0 is Monday – Shuai Wang Jun 23 '21 at 16:03
  • 1
    OK the difference is that my local timezone is EST but the jenkins machine is on GMT – Shuai Wang Jun 23 '21 at 16:27
  • 1
    I like this answer. Here to make it work in any timezone: `function daysForLocale(localeName = 'en-US', weekday = 'long') { let now = new Date() const format = new Intl.DateTimeFormat(localeName, { weekday }).format; return [...Array(7).keys()] .map((day) => format(new Date().getTime() - ( now.getDay() - day ) * 86400000 )); }` – Jay Dee Aug 12 '21 at 19:29
  • Why specifically use 2021 and 5 as date arguments? – Audun Olsen Dec 17 '21 at 14:53
7

 const weekdayDateMap = {
  Mon: new Date('2020-01-06T00:00:00.000Z'),
  Tue: new Date('2020-01-07T00:00:00.000Z'),
  Wed: new Date('2020-01-08T00:00:00.000Z'),
  Thu: new Date('2020-01-09T00:00:00.000Z'),
  Fri: new Date('2020-01-10T00:00:00.000Z'),
  Sat: new Date('2020-01-11T00:00:00.000Z'),
  Sun: new Date('2020-01-12T00:00:00.000Z'),
};
const shortWeekdays = Object.keys(weekdayDateMap);

const getDayOfWeek = (shortName, locale = 'en-US', length = 'short') =>
  new Intl.DateTimeFormat(locale, { weekday: length }).format(weekdayDateMap[shortName]);

const getDaysOfWeek = (locale = 'en-US', length = 'short') =>
  shortWeekdays.map(shortName => getDayOfWeek(shortName, locale, length));


console.log(getDayOfWeek('Mon', 'de-DE')) // "Mo"

console.log(getDaysOfWeek('de-DE')) // ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]

Note:

If you're calling the Intl.DateTimeFormat formatter many times a second, it's more efficient to create the formatter once and re-use it.

Dominic
  • 62,658
  • 20
  • 139
  • 163
1

Intl (ergo Intl.js as well) doesn't have an API to get weekday names yet, so you'll have to do the hack-thing of querying a bunch of days with the right options. It's possible it may add support for doing so in the future, but right now you're basically out of luck. (At least, unless you manually augment Intl.js with a fix.)

Jeff Walden
  • 7,008
  • 2
  • 38
  • 55
0

Trying to improve on the most popular answer; Also to answer the question:

Why use Date.UTC(2021, 1, day+1) to initialize?

Because, you need to find an actual calendar week where you can extract the weekdays string from.

    function getWeekdayLocale(localeName = 'fr', weekday = 'long') {
          const format = new Intl.DateTimeFormat(localeName, { weekday }).format;
          return [...Array(7).keys()]
            .map((day) => format(new Date(Date.UTC(2021, 1, day+1))));
    }
    console.log(getWeekdayLocale())
dhwang
  • 57
  • 8
0

Here is a version that does not have to hardcode the start date

const format = (date) => new Intl.DateTimeFormat('ca', { 'weekday': 'long' }).format(date);
const d = new Date();
d.setHours(15, 0, 0, 0); /* normalise */
d.setDate(d.getDate() - d.getDay() - 1); /* Saturday */
const localeDayNames = [...Array(7)]
  .map((_, i) => format(d.setDate(d.getDate() + 1)));
console.log(localeDayNames);
mplungjan
  • 169,008
  • 28
  • 173
  • 236
-1

Much simpler solution:

let d = new Date();
let day_options = {
    timeZone: "America/New_York",
    weekday:"short"
};
let formatter = new Intl.DateTimeFormat([],day_options);
console.log(formatter.format(d));

Output: Thu

user3483642
  • 325
  • 2
  • 5
  • This is always today's date, so my output is "Mon". OP is also asking for the names of all the days, not just today's. – Ian Kim Apr 11 '23 at 01:18