1import { addFormatToken } from '../format/format';
2import { addRegexToken, matchUnsigned, regexEscape } from '../parse/regex';
3import { addParseToken } from '../parse/token';
4import { YEAR } from './constants';
5import { hooks as moment } from '../utils/hooks';
6import { getLocale } from '../locale/locales';
7import getParsingFlags from '../create/parsing-flags';
8import hasOwnProp from '../utils/has-own-prop';
9
10addFormatToken('N', 0, 0, 'eraAbbr');
11addFormatToken('NN', 0, 0, 'eraAbbr');
12addFormatToken('NNN', 0, 0, 'eraAbbr');
13addFormatToken('NNNN', 0, 0, 'eraName');
14addFormatToken('NNNNN', 0, 0, 'eraNarrow');
15
16addFormatToken('y', ['y', 1], 'yo', 'eraYear');
17addFormatToken('y', ['yy', 2], 0, 'eraYear');
18addFormatToken('y', ['yyy', 3], 0, 'eraYear');
19addFormatToken('y', ['yyyy', 4], 0, 'eraYear');
20
21addRegexToken('N', matchEraAbbr);
22addRegexToken('NN', matchEraAbbr);
23addRegexToken('NNN', matchEraAbbr);
24addRegexToken('NNNN', matchEraName);
25addRegexToken('NNNNN', matchEraNarrow);
26
27addParseToken(
28 ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'],
29 function (input, array, config, token) {
30 var era = config._locale.erasParse(input, token, config._strict);
31 if (era) {
32 getParsingFlags(config).era = era;
33 } else {
34 getParsingFlags(config).invalidEra = input;
35 }
36 }
37);
38
39addRegexToken('y', matchUnsigned);
40addRegexToken('yy', matchUnsigned);
41addRegexToken('yyy', matchUnsigned);
42addRegexToken('yyyy', matchUnsigned);
43addRegexToken('yo', matchEraYearOrdinal);
44
45addParseToken(['y', 'yy', 'yyy', 'yyyy'], YEAR);
46addParseToken(['yo'], function (input, array, config, token) {
47 var match;
48 if (config._locale._eraYearOrdinalRegex) {
49 match = input.match(config._locale._eraYearOrdinalRegex);
50 }
51
52 if (config._locale.eraYearOrdinalParse) {
53 array[YEAR] = config._locale.eraYearOrdinalParse(input, match);
54 } else {
55 array[YEAR] = parseInt(input, 10);
56 }
57});
58
59export function localeEras(m, format) {
60 var i,
61 l,
62 date,
63 eras = this._eras || getLocale('en')._eras;
64 for (i = 0, l = eras.length; i < l; ++i) {
65 switch (typeof eras[i].since) {
66 case 'string':
67 // truncate time
68 date = moment(eras[i].since).startOf('day');
69 eras[i].since = date.valueOf();
70 break;
71 }
72
73 switch (typeof eras[i].until) {
74 case 'undefined':
75 eras[i].until = +Infinity;
76 break;
77 case 'string':
78 // truncate time
79 date = moment(eras[i].until).startOf('day').valueOf();
80 eras[i].until = date.valueOf();
81 break;
82 }
83 }
84 return eras;
85}
86
87export function localeErasParse(eraName, format, strict) {
88 var i,
89 l,
90 eras = this.eras(),
91 name,
92 abbr,
93 narrow;
94 eraName = eraName.toUpperCase();
95
96 for (i = 0, l = eras.length; i < l; ++i) {
97 name = eras[i].name.toUpperCase();
98 abbr = eras[i].abbr.toUpperCase();
99 narrow = eras[i].narrow.toUpperCase();
100
101 if (strict) {
102 switch (format) {
103 case 'N':
104 case 'NN':
105 case 'NNN':
106 if (abbr === eraName) {
107 return eras[i];
108 }
109 break;
110
111 case 'NNNN':
112 if (name === eraName) {
113 return eras[i];
114 }
115 break;
116
117 case 'NNNNN':
118 if (narrow === eraName) {
119 return eras[i];
120 }
121 break;
122 }
123 } else if ([name, abbr, narrow].indexOf(eraName) >= 0) {
124 return eras[i];
125 }
126 }
127}
128
129export function localeErasConvertYear(era, year) {
130 var dir = era.since <= era.until ? +1 : -1;
131 if (year === undefined) {
132 return moment(era.since).year();
133 } else {
134 return moment(era.since).year() + (year - era.offset) * dir;
135 }
136}
137
138export function getEraName() {
139 var i,
140 l,
141 val,
142 eras = this.localeData().eras();
143 for (i = 0, l = eras.length; i < l; ++i) {
144 // truncate time
145 val = this.clone().startOf('day').valueOf();
146
147 if (eras[i].since <= val && val <= eras[i].until) {
148 return eras[i].name;
149 }
150 if (eras[i].until <= val && val <= eras[i].since) {
151 return eras[i].name;
152 }
153 }
154
155 return '';
156}
157
158export function getEraNarrow() {
159 var i,
160 l,
161 val,
162 eras = this.localeData().eras();
163 for (i = 0, l = eras.length; i < l; ++i) {
164 // truncate time
165 val = this.clone().startOf('day').valueOf();
166
167 if (eras[i].since <= val && val <= eras[i].until) {
168 return eras[i].narrow;
169 }
170 if (eras[i].until <= val && val <= eras[i].since) {
171 return eras[i].narrow;
172 }
173 }
174
175 return '';
176}
177
178export function getEraAbbr() {
179 var i,
180 l,
181 val,
182 eras = this.localeData().eras();
183 for (i = 0, l = eras.length; i < l; ++i) {
184 // truncate time
185 val = this.clone().startOf('day').valueOf();
186
187 if (eras[i].since <= val && val <= eras[i].until) {
188 return eras[i].abbr;
189 }
190 if (eras[i].until <= val && val <= eras[i].since) {
191 return eras[i].abbr;
192 }
193 }
194
195 return '';
196}
197
198export function getEraYear() {
199 var i,
200 l,
201 dir,
202 val,
203 eras = this.localeData().eras();
204 for (i = 0, l = eras.length; i < l; ++i) {
205 dir = eras[i].since <= eras[i].until ? +1 : -1;
206
207 // truncate time
208 val = this.clone().startOf('day').valueOf();
209
210 if (
211 (eras[i].since <= val && val <= eras[i].until) ||
212 (eras[i].until <= val && val <= eras[i].since)
213 ) {
214 return (
215 (this.year() - moment(eras[i].since).year()) * dir +
216 eras[i].offset
217 );
218 }
219 }
220
221 return this.year();
222}
223
224export function erasNameRegex(isStrict) {
225 if (!hasOwnProp(this, '_erasNameRegex')) {
226 computeErasParse.call(this);
227 }
228 return isStrict ? this._erasNameRegex : this._erasRegex;
229}
230
231export function erasAbbrRegex(isStrict) {
232 if (!hasOwnProp(this, '_erasAbbrRegex')) {
233 computeErasParse.call(this);
234 }
235 return isStrict ? this._erasAbbrRegex : this._erasRegex;
236}
237
238export function erasNarrowRegex(isStrict) {
239 if (!hasOwnProp(this, '_erasNarrowRegex')) {
240 computeErasParse.call(this);
241 }
242 return isStrict ? this._erasNarrowRegex : this._erasRegex;
243}
244
245function matchEraAbbr(isStrict, locale) {
246 return locale.erasAbbrRegex(isStrict);
247}
248
249function matchEraName(isStrict, locale) {
250 return locale.erasNameRegex(isStrict);
251}
252
253function matchEraNarrow(isStrict, locale) {
254 return locale.erasNarrowRegex(isStrict);
255}
256
257function matchEraYearOrdinal(isStrict, locale) {
258 return locale._eraYearOrdinalRegex || matchUnsigned;
259}
260
261function computeErasParse() {
262 var abbrPieces = [],
263 namePieces = [],
264 narrowPieces = [],
265 mixedPieces = [],
266 i,
267 l,
268 eras = this.eras();
269
270 for (i = 0, l = eras.length; i < l; ++i) {
271 namePieces.push(regexEscape(eras[i].name));
272 abbrPieces.push(regexEscape(eras[i].abbr));
273 narrowPieces.push(regexEscape(eras[i].narrow));
274
275 mixedPieces.push(regexEscape(eras[i].name));
276 mixedPieces.push(regexEscape(eras[i].abbr));
277 mixedPieces.push(regexEscape(eras[i].narrow));
278 }
279
280 this._erasRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
281 this._erasNameRegex = new RegExp('^(' + namePieces.join('|') + ')', 'i');
282 this._erasAbbrRegex = new RegExp('^(' + abbrPieces.join('|') + ')', 'i');
283 this._erasNarrowRegex = new RegExp(
284 '^(' + narrowPieces.join('|') + ')',
285 'i'
286 );
287}