6

Well, the title is pretty explanatory - I need to figure out the day week start in local - it can be Monday, Sunday, Saturday or Friday - in pure Javascript.

I found this https://stackoverflow.com/a/727536/1226226

<firstDay day="mon" territories="001 AD AI AL AM AN AT AX AZ BA BE BG BM BN BY CH CL CM CR CY CZ DE DK EC EE ES FI FJ FO FR GB GE GF GP GR HR HU IS IT KG KZ LB LI LK LT LU LV MC MD ME MK MN MQ MY NL NO PL PT RE RO RS RU SE SI SK SM TJ TM TR UA UY UZ VA VN XK" />
<firstDay day="fri" territories="BD MV" />
<firstDay day="sat" territories="AE AF BH DJ DZ EG IQ IR JO KW LY MA OM QA SD SY" />
<firstDay day="sun" territories="AG AR AS AU BR BS BT BW BZ CA CN CO DM DO ET GT GU HK HN ID IE IL IN JM JP KE KH KR LA MH MM MO MT MX MZ NI NP NZ PA PE PH PK PR PY SA SG SV TH TN TT TW UM US VE VI WS YE ZA ZW" />
<firstDay day="sun" territories="GB" alt="variant" references="Shorter Oxford Dictionary (5th edition, 2002)" />

found a compatible table of ISO3166 and ISO639 codes - https://wiki.openstreetmap.org/wiki/Nominatim/Country_Codes

Oleh Melnyk
  • 337
  • 5
  • 11
  • 1
    https://stackoverflow.com/questions/5210376/how-to-get-first-and-last-day-of-the-week-in-javascript – JM-AGMS Nov 19 '18 at 21:01
  • Possible duplicate of [How to get first and last day of the week in JavaScript](https://stackoverflow.com/questions/5210376/how-to-get-first-and-last-day-of-the-week-in-javascript) – hindmost Nov 19 '18 at 21:08
  • @hindmost - nope, this code shows that the first day of the week is Sunday, but in my current locale it should be Monday – Oleh Melnyk Nov 19 '18 at 21:19
  • Fitting that answer to your specific need is trivial. – hindmost Nov 19 '18 at 21:23
  • 5
    @hindmost - not so trivial to me - there are countries where weeks start from Monday, Sunday, Saturday or even Friday – Oleh Melnyk Nov 19 '18 at 21:26
  • The first day of the week is not necessarily based on any particular rule. A person might prefer a particular day for administrative, religious or personal reasons, and might use a different day depending on context. I think the only way to get it right is to ask. Language (I guess [*NavigatorLanguage.language*](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/language)) is unreliable and locale (i.e. actual geographic location, not language) is not much better, but it may be more reliable where administrative rules are concerned. – RobG Nov 20 '18 at 01:40
  • I'm not aware of any way that does not rely on an external lookup table. But I think even if the first day of the week based on language-country might not always be correct, it is certainly better than to just assume "Sunday" like many services do. – str Nov 20 '18 at 10:20

4 Answers4

8

Without moment. Essentially a heavily golfed version of https://github.com/gamtiq/weekstart, ignoring some unusual locales. No pure JS answer (using APIs available as of 2020) is going to be perfect, but this will yield the same result as a system API would for at least 99.9% of users.

https://github.com/tc39/proposal-intl-locale-info has been proposed which will include an API level solution for this.

function weekStart(region, language) {
  const regionSat = 'AEAFBHDJDZEGIQIRJOKWLYOMQASDSY'.match(/../g);
  const regionSun = 'AGARASAUBDBRBSBTBWBZCACNCODMDOETGTGUHKHNIDILINJMJPKEKHKRLAMHMMMOMTMXMZNINPPAPEPHPKPRPTPYSASGSVTHTTTWUMUSVEVIWSYEZAZW'.match(/../g);
  const languageSat = ['ar','arq','arz','fa'];
  const languageSun = 'amasbndzengnguhehiidjajvkmknkolomhmlmrmtmyneomorpapssdsmsnsutatethtnurzhzu'.match(/../g);

  return (
    region ? (
      regionSun.includes(region) ? 'sun' :
      regionSat.includes(region) ? 'sat' : 'mon') : (
      languageSun.includes(language) ? 'sun' :
      languageSat.includes(language) ? 'sat' : 'mon'));
}

function weekStartLocale(locale) {
  const parts = locale.match(/^([a-z]{2,3})(?:-([a-z]{3})(?=$|-))?(?:-([a-z]{4})(?=$|-))?(?:-([a-z]{2}|\d{3})(?=$|-))?/i);
  return weekStart(parts[4], parts[1]);
}

console.log(weekStartLocale(navigator.language));
console.log(weekStartLocale('en'));
console.log(weekStartLocale('en-GB'));
console.log(weekStartLocale('ar-AE'));
Adam Leggett
  • 3,714
  • 30
  • 24
  • Impressive golfing for something that usually implies loading a lot of data. I’m curious how complete this is and whether you think it could be generated? – Semicolon Dec 05 '19 at 15:14
  • 1
    @Semicolon I lost the link to the JSON database I derived this from. https://github.com/gamtiq/weekstart is a more complete solution now; I may golf this one and post the results here. – Adam Leggett Dec 05 '19 at 15:56
  • Thanks. I’d add that the regexp for language tags here isn’t quite right — there won’t be underscores, for example — though perhaps these differences (which would rarely matter in practice) are addressing known issues in some agents. This is what I’d ended up using, derived from your answer: https://gist.github.com/bathos/84286d0d6052d10dd98a444d41e9db43 Thanks again — I’ll check out that link! – Semicolon Dec 06 '19 at 11:41
  • @Semicolon no user agent should be sending an underscore as the separator: https://tools.ietf.org/html/bcp47 – Adam Leggett Dec 06 '19 at 20:55
  • Yes, I agree. I must have stated that ambiguously, sorry. What I meant was that the RegExp pattern above *is* allowing for underscore as separator, which afaik isn’t necessary (though I wasn’t sure if maybe there was some known agent divergence being accounted for). – Semicolon Dec 06 '19 at 20:58
  • D'oh. You are right. I got the regex from somewhere else. This was all the result of scavenging. – Adam Leggett Dec 06 '19 at 20:59
  • If it’s useful: the pattern in the gist linked to above should adhere to https://tools.ietf.org/html/rfc5646#section-2.1 aside from omiting grandfathered tags, numeric region tags, and ignoring everything after region. – Semicolon Dec 06 '19 at 21:01
  • 1
    @Semicolon finally got around to golfing the better answer. – Adam Leggett Jul 24 '20 at 15:00
2

As of lately you can use: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/weekInfo

It is available in all browsers (except firefox: March 2023)

code looks like this:

new Intl.Locale(navigator.language).weekInfo.firstDay // 1 or 7 ...

you can check for any locale by changing navigator.language with the desired language ex:

new Intl.Locale('fr').weekInfo.firstDay // 1
user1928596
  • 1,503
  • 16
  • 21
1

A more maintainable and usable version based on CLDR.

Based on country code. Returns 0 for Sunday, 1 for Monday, -1 for Saturday and -2 for Friday so you can use it to make a calendar. Returns 1 for unknown country codes.

{
let wso = { // fri:1, sat:2, sun:3
    MV:1,
    AE:2,AF:2,BH:2,DJ:2,DZ:2,EG:2,IQ:2,IR:2,JO:2,KW:2,LY:2,OM:2,QA:2,SD:2,SY:2,
    AG:3,AS:3,AU:3,BD:3,BR:3,BS:3,BT:3,BW:3,BZ:3,CA:3,CN:3,CO:3,DM:3,DO:3,ET:3,
    GT:3,GU:3,HK:3,HN:3,ID:3,IL:3,IN:3,JM:3,JP:3,KE:3,KH:3,KR:3,LA:3,MH:3,MM:3,
    MO:3,MT:3,MX:3,MZ:3,NI:3,NP:3,PA:3,PE:3,PH:3,PK:3,PR:3,PT:3,PY:3,SA:3,SG:3,
    SV:3,TH:3,TT:3,TW:3,UM:3,US:3,VE:3,VI:3,WS:3,YE:3,ZA:3,ZW:3,
}
function week_start_offset(country) {
    return (wso[country] || 4) - 3
}
}

console.log(week_start_offset('US'))
console.log(week_start_offset('RO'))
capr
  • 149
  • 1
  • 8
-3

you could use moment.js

moment.localeData('en-us').firstDayOfWeek();

As for pure js, you would have to make your own lookup table. You can use momentjs source code for reference. https://github.com/moment/moment/tree/develop/locale

In each of each locale file look for the dow at the end of the config.

Matt
  • 2,096
  • 14
  • 20
  • I wish I could, but I can't use any 3rd party libraries – Oleh Melnyk Nov 19 '18 at 21:03
  • There is no built in way. Your best luck is to make a mapping of locales to firstDayOfTheWeek. It would be possible to make a lookup table for every locale. – Matt Nov 19 '18 at 21:17
  • @Matt—the language is a very unreliable way of getting the user's locale or their preferred first day of the week. – RobG Nov 20 '18 at 01:34