123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- export const fields = {
- G: { field: 'era', desc: 'Era' },
- y: { field: 'year', desc: 'Year' },
- Y: { field: 'year', desc: 'Year of "Week of Year"' },
- u: { field: 'year', desc: 'Extended year' },
- U: { field: 'year', desc: 'Cyclic year name' },
- r: { field: 'year', desc: 'Related Gregorian year' },
- Q: { field: 'quarter', desc: 'Quarter' },
- q: { field: 'quarter', desc: 'Stand-alone quarter' },
- M: { field: 'month', desc: 'Month in year' },
- L: { field: 'month', desc: 'Stand-alone month in year' },
- w: { field: 'week', desc: 'Week of year' },
- W: { field: 'week', desc: 'Week of month' },
- d: { field: 'day', desc: 'Day in month' },
- D: { field: 'day', desc: 'Day of year' },
- F: { field: 'day', desc: 'Day of week in month' },
- g: { field: 'day', desc: 'Modified julian day' },
- E: { field: 'weekday', desc: 'Day of week' },
- e: { field: 'weekday', desc: 'Local day of week' },
- c: { field: 'weekday', desc: 'Stand-alone local day of week' },
- a: { field: 'period', desc: 'AM/PM marker' },
- b: { field: 'period', desc: 'AM/PM/noon/midnight marker' },
- B: { field: 'period', desc: 'Flexible day period' },
- h: { field: 'hour', desc: 'Hour in AM/PM (1~12)' },
- H: { field: 'hour', desc: 'Hour in day (0~23)' },
- k: { field: 'hour', desc: 'Hour in day (1~24)' },
- K: { field: 'hour', desc: 'Hour in AM/PM (0~11)' },
- j: { field: 'hour', desc: 'Hour in preferred cycle' },
- J: { field: 'hour', desc: 'Hour in preferred cycle without marker' },
- C: { field: 'hour', desc: 'Hour in preferred cycle with flexible marker' },
- m: { field: 'min', desc: 'Minute in hour' },
- s: { field: 'sec', desc: 'Second in minute' },
- S: { field: 'sec-frac', desc: 'Fractional second' },
- A: { field: 'ms', desc: 'Milliseconds in day' },
- z: { field: 'tz', desc: 'Time Zone: specific non-location' },
- Z: { field: 'tz', desc: 'Time Zone' },
- O: { field: 'tz', desc: 'Time Zone: localized' },
- v: { field: 'tz', desc: 'Time Zone: generic non-location' },
- V: { field: 'tz', desc: 'Time Zone: ID' },
- X: { field: 'tz', desc: 'Time Zone: ISO8601 with Z' },
- x: { field: 'tz', desc: 'Time Zone: ISO8601' }
- };
- const isLetter = (char) => (char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z');
- function readFieldToken(src, pos) {
- const char = src[pos];
- let width = 1;
- while (src[++pos] === char)
- ++width;
- const field = fields[char];
- if (!field) {
- const msg = `The letter ${char} is not a valid field identifier`;
- return { char, error: new Error(msg), width };
- }
- return { char, field: field.field, desc: field.desc, width };
- }
- function readQuotedToken(src, pos) {
- let str = src[++pos];
- let width = 2;
- if (str === "'")
- return { char: "'", str, width };
- while (true) {
- const next = src[++pos];
- ++width;
- if (next === undefined) {
- const msg = `Unterminated quoted literal in pattern: ${str || src}`;
- return { char: "'", error: new Error(msg), str, width };
- }
- else if (next === "'") {
- if (src[++pos] !== "'")
- return { char: "'", str, width };
- else
- ++width;
- }
- str += next;
- }
- }
- function readToken(src, pos) {
- const char = src[pos];
- if (!char)
- return null;
- if (isLetter(char))
- return readFieldToken(src, pos);
- if (char === "'")
- return readQuotedToken(src, pos);
- let str = char;
- let width = 1;
- while (true) {
- const next = src[++pos];
- if (!next || isLetter(next) || next === "'")
- return { char, str, width };
- str += next;
- width += 1;
- }
- }
- /**
- * Parse an {@link http://userguide.icu-project.org/formatparse/datetime | ICU
- * DateFormat skeleton} string into a {@link DateToken} array.
- *
- * @remarks
- * Errors will not be thrown, but if encountered are included as the relevant
- * token's `error` value.
- *
- * @public
- * @param src - The skeleton string
- *
- * @example
- * ```js
- * import { parseDateTokens } from '@messageformat/date-skeleton'
- *
- * parseDateTokens('GrMMMdd', console.error)
- * // [
- * // { char: 'G', field: 'era', desc: 'Era', width: 1 },
- * // { char: 'r', field: 'year', desc: 'Related Gregorian year', width: 1 },
- * // { char: 'M', field: 'month', desc: 'Month in year', width: 3 },
- * // { char: 'd', field: 'day', desc: 'Day in month', width: 2 }
- * // ]
- * ```
- */
- export function parseDateTokens(src) {
- const tokens = [];
- let pos = 0;
- while (true) {
- const token = readToken(src, pos);
- if (!token)
- return tokens;
- tokens.push(token);
- pos += token.width;
- }
- }
|