1import { addFormatToken } from '../format/format';
2import { addUnitAlias } from './aliases';
3import { addUnitPriority } from './priorities';
4import {
5 addRegexToken,
6 match1to2,
7 matchWord,
8 regexEscape,
9} from '../parse/regex';
10import { addWeekParseToken } from '../parse/token';
11import toInt from '../utils/to-int';
12import isArray from '../utils/is-array';
13import indexOf from '../utils/index-of';
14import hasOwnProp from '../utils/has-own-prop';
15import { createUTC } from '../create/utc';
16import getParsingFlags from '../create/parsing-flags';
17
18// FORMATTING
19
20addFormatToken('d', 0, 'do', 'day');
21
22addFormatToken('dd', 0, 0, function (format) {
23 return this.localeData().weekdaysMin(this, format);
24});
25
26addFormatToken('ddd', 0, 0, function (format) {
27 return this.localeData().weekdaysShort(this, format);
28});
29
30addFormatToken('dddd', 0, 0, function (format) {
31 return this.localeData().weekdays(this, format);
32});
33
34addFormatToken('e', 0, 0, 'weekday');
35addFormatToken('E', 0, 0, 'isoWeekday');
36
37// ALIASES
38
39addUnitAlias('day', 'd');
40addUnitAlias('weekday', 'e');
41addUnitAlias('isoWeekday', 'E');
42
43// PRIORITY
44addUnitPriority('day', 11);
45addUnitPriority('weekday', 11);
46addUnitPriority('isoWeekday', 11);
47
48// PARSING
49
50addRegexToken('d', match1to2);
51addRegexToken('e', match1to2);
52addRegexToken('E', match1to2);
53addRegexToken('dd', function (isStrict, locale) {
54 return locale.weekdaysMinRegex(isStrict);
55});
56addRegexToken('ddd', function (isStrict, locale) {
57 return locale.weekdaysShortRegex(isStrict);
58});
59addRegexToken('dddd', function (isStrict, locale) {
60 return locale.weekdaysRegex(isStrict);
61});
62
63addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
64 var weekday = config._locale.weekdaysParse(input, token, config._strict);
65 // if we didn't get a weekday name, mark the date as invalid
66 if (weekday != null) {
67 week.d = weekday;
68 } else {
69 getParsingFlags(config).invalidWeekday = input;
70 }
71});
72
73addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
74 week[token] = toInt(input);
75});
76
77// HELPERS
78
79function parseWeekday(input, locale) {
80 if (typeof input !== 'string') {
81 return input;
82 }
83
84 if (!isNaN(input)) {
85 return parseInt(input, 10);
86 }
87
88 input = locale.weekdaysParse(input);
89 if (typeof input === 'number') {
90 return input;
91 }
92
93 return null;
94}
95
96function parseIsoWeekday(input, locale) {
97 if (typeof input === 'string') {
98 return locale.weekdaysParse(input) % 7 || 7;
99 }
100 return isNaN(input) ? null : input;
101}
102
103// LOCALES
104function shiftWeekdays(ws, n) {
105 return ws.slice(n, 7).concat(ws.slice(0, n));
106}
107
108var defaultLocaleWeekdays =
109 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
110 defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
111 defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
112 defaultWeekdaysRegex = matchWord,
113 defaultWeekdaysShortRegex = matchWord,
114 defaultWeekdaysMinRegex = matchWord;
115
116export {
117 defaultLocaleWeekdays,
118 defaultLocaleWeekdaysShort,
119 defaultLocaleWeekdaysMin,
120};
121
122export function localeWeekdays(m, format) {
123 var weekdays = isArray(this._weekdays)
124 ? this._weekdays
125 : this._weekdays[
126 m && m !== true && this._weekdays.isFormat.test(format)
127 ? 'format'
128 : 'standalone'
129 ];
130 return m === true
131 ? shiftWeekdays(weekdays, this._week.dow)
132 : m
133 ? weekdays[m.day()]
134 : weekdays;
135}
136
137export function localeWeekdaysShort(m) {
138 return m === true
139 ? shiftWeekdays(this._weekdaysShort, this._week.dow)
140 : m
141 ? this._weekdaysShort[m.day()]
142 : this._weekdaysShort;
143}
144
145export function localeWeekdaysMin(m) {
146 return m === true
147 ? shiftWeekdays(this._weekdaysMin, this._week.dow)
148 : m
149 ? this._weekdaysMin[m.day()]
150 : this._weekdaysMin;
151}
152
153function handleStrictParse(weekdayName, format, strict) {
154 var i,
155 ii,
156 mom,
157 llc = weekdayName.toLocaleLowerCase();
158 if (!this._weekdaysParse) {
159 this._weekdaysParse = [];
160 this._shortWeekdaysParse = [];
161 this._minWeekdaysParse = [];
162
163 for (i = 0; i < 7; ++i) {
164 mom = createUTC([2000, 1]).day(i);
165 this._minWeekdaysParse[i] = this.weekdaysMin(
166 mom,
167 ''
168 ).toLocaleLowerCase();
169 this._shortWeekdaysParse[i] = this.weekdaysShort(
170 mom,
171 ''
172 ).toLocaleLowerCase();
173 this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
174 }
175 }
176
177 if (strict) {
178 if (format === 'dddd') {
179 ii = indexOf.call(this._weekdaysParse, llc);
180 return ii !== -1 ? ii : null;
181 } else if (format === 'ddd') {
182 ii = indexOf.call(this._shortWeekdaysParse, llc);
183 return ii !== -1 ? ii : null;
184 } else {
185 ii = indexOf.call(this._minWeekdaysParse, llc);
186 return ii !== -1 ? ii : null;
187 }
188 } else {
189 if (format === 'dddd') {
190 ii = indexOf.call(this._weekdaysParse, llc);
191 if (ii !== -1) {
192 return ii;
193 }
194 ii = indexOf.call(this._shortWeekdaysParse, llc);
195 if (ii !== -1) {
196 return ii;
197 }
198 ii = indexOf.call(this._minWeekdaysParse, llc);
199 return ii !== -1 ? ii : null;
200 } else if (format === 'ddd') {
201 ii = indexOf.call(this._shortWeekdaysParse, llc);
202 if (ii !== -1) {
203 return ii;
204 }
205 ii = indexOf.call(this._weekdaysParse, llc);
206 if (ii !== -1) {
207 return ii;
208 }
209 ii = indexOf.call(this._minWeekdaysParse, llc);
210 return ii !== -1 ? ii : null;
211 } else {
212 ii = indexOf.call(this._minWeekdaysParse, llc);
213 if (ii !== -1) {
214 return ii;
215 }
216 ii = indexOf.call(this._weekdaysParse, llc);
217 if (ii !== -1) {
218 return ii;
219 }
220 ii = indexOf.call(this._shortWeekdaysParse, llc);
221 return ii !== -1 ? ii : null;
222 }
223 }
224}
225
226export function localeWeekdaysParse(weekdayName, format, strict) {
227 var i, mom, regex;
228
229 if (this._weekdaysParseExact) {
230 return handleStrictParse.call(this, weekdayName, format, strict);
231 }
232
233 if (!this._weekdaysParse) {
234 this._weekdaysParse = [];
235 this._minWeekdaysParse = [];
236 this._shortWeekdaysParse = [];
237 this._fullWeekdaysParse = [];
238 }
239
240 for (i = 0; i < 7; i++) {
241 // make the regex if we don't have it already
242
243 mom = createUTC([2000, 1]).day(i);
244 if (strict && !this._fullWeekdaysParse[i]) {
245 this._fullWeekdaysParse[i] = new RegExp(
246 '^' + this.weekdays(mom, '').replace('.', '\\.?') + '$',
247 'i'
248 );
249 this._shortWeekdaysParse[i] = new RegExp(
250 '^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$',
251 'i'
252 );
253 this._minWeekdaysParse[i] = new RegExp(
254 '^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$',
255 'i'
256 );
257 }
258 if (!this._weekdaysParse[i]) {
259 regex =
260 '^' +
261 this.weekdays(mom, '') +
262 '|^' +
263 this.weekdaysShort(mom, '') +
264 '|^' +
265 this.weekdaysMin(mom, '');
266 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
267 }
268 // test the regex
269 if (
270 strict &&
271 format === 'dddd' &&
272 this._fullWeekdaysParse[i].test(weekdayName)
273 ) {
274 return i;
275 } else if (
276 strict &&
277 format === 'ddd' &&
278 this._shortWeekdaysParse[i].test(weekdayName)
279 ) {
280 return i;
281 } else if (
282 strict &&
283 format === 'dd' &&
284 this._minWeekdaysParse[i].test(weekdayName)
285 ) {
286 return i;
287 } else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
288 return i;
289 }
290 }
291}
292
293// MOMENTS
294
295export function getSetDayOfWeek(input) {
296 if (!this.isValid()) {
297 return input != null ? this : NaN;
298 }
299 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
300 if (input != null) {
301 input = parseWeekday(input, this.localeData());
302 return this.add(input - day, 'd');
303 } else {
304 return day;
305 }
306}
307
308export function getSetLocaleDayOfWeek(input) {
309 if (!this.isValid()) {
310 return input != null ? this : NaN;
311 }
312 var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
313 return input == null ? weekday : this.add(input - weekday, 'd');
314}
315
316export function getSetISODayOfWeek(input) {
317 if (!this.isValid()) {
318 return input != null ? this : NaN;
319 }
320
321 // behaves the same as moment#day except
322 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
323 // as a setter, sunday should belong to the previous week.
324
325 if (input != null) {
326 var weekday = parseIsoWeekday(input, this.localeData());
327 return this.day(this.day() % 7 ? weekday : weekday - 7);
328 } else {
329 return this.day() || 7;
330 }
331}
332
333export function weekdaysRegex(isStrict) {
334 if (this._weekdaysParseExact) {
335 if (!hasOwnProp(this, '_weekdaysRegex')) {
336 computeWeekdaysParse.call(this);
337 }
338 if (isStrict) {
339 return this._weekdaysStrictRegex;
340 } else {
341 return this._weekdaysRegex;
342 }
343 } else {
344 if (!hasOwnProp(this, '_weekdaysRegex')) {
345 this._weekdaysRegex = defaultWeekdaysRegex;
346 }
347 return this._weekdaysStrictRegex && isStrict
348 ? this._weekdaysStrictRegex
349 : this._weekdaysRegex;
350 }
351}
352
353export function weekdaysShortRegex(isStrict) {
354 if (this._weekdaysParseExact) {
355 if (!hasOwnProp(this, '_weekdaysRegex')) {
356 computeWeekdaysParse.call(this);
357 }
358 if (isStrict) {
359 return this._weekdaysShortStrictRegex;
360 } else {
361 return this._weekdaysShortRegex;
362 }
363 } else {
364 if (!hasOwnProp(this, '_weekdaysShortRegex')) {
365 this._weekdaysShortRegex = defaultWeekdaysShortRegex;
366 }
367 return this._weekdaysShortStrictRegex && isStrict
368 ? this._weekdaysShortStrictRegex
369 : this._weekdaysShortRegex;
370 }
371}
372
373export function weekdaysMinRegex(isStrict) {
374 if (this._weekdaysParseExact) {
375 if (!hasOwnProp(this, '_weekdaysRegex')) {
376 computeWeekdaysParse.call(this);
377 }
378 if (isStrict) {
379 return this._weekdaysMinStrictRegex;
380 } else {
381 return this._weekdaysMinRegex;
382 }
383 } else {
384 if (!hasOwnProp(this, '_weekdaysMinRegex')) {
385 this._weekdaysMinRegex = defaultWeekdaysMinRegex;
386 }
387 return this._weekdaysMinStrictRegex && isStrict
388 ? this._weekdaysMinStrictRegex
389 : this._weekdaysMinRegex;
390 }
391}
392
393function computeWeekdaysParse() {
394 function cmpLenRev(a, b) {
395 return b.length - a.length;
396 }
397
398 var minPieces = [],
399 shortPieces = [],
400 longPieces = [],
401 mixedPieces = [],
402 i,
403 mom,
404 minp,
405 shortp,
406 longp;
407 for (i = 0; i < 7; i++) {
408 // make the regex if we don't have it already
409 mom = createUTC([2000, 1]).day(i);
410 minp = regexEscape(this.weekdaysMin(mom, ''));
411 shortp = regexEscape(this.weekdaysShort(mom, ''));
412 longp = regexEscape(this.weekdays(mom, ''));
413 minPieces.push(minp);
414 shortPieces.push(shortp);
415 longPieces.push(longp);
416 mixedPieces.push(minp);
417 mixedPieces.push(shortp);
418 mixedPieces.push(longp);
419 }
420 // Sorting makes sure if one weekday (or abbr) is a prefix of another it
421 // will match the longer piece.
422 minPieces.sort(cmpLenRev);
423 shortPieces.sort(cmpLenRev);
424 longPieces.sort(cmpLenRev);
425 mixedPieces.sort(cmpLenRev);
426
427 this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
428 this._weekdaysShortRegex = this._weekdaysRegex;
429 this._weekdaysMinRegex = this._weekdaysRegex;
430
431 this._weekdaysStrictRegex = new RegExp(
432 '^(' + longPieces.join('|') + ')',
433 'i'
434 );
435 this._weekdaysShortStrictRegex = new RegExp(
436 '^(' + shortPieces.join('|') + ')',
437 'i'
438 );
439 this._weekdaysMinStrictRegex = new RegExp(
440 '^(' + minPieces.join('|') + ')',
441 'i'
442 );
443}