diff --git a/src/parse/index.js b/src/parse/index.js index 4dc906fad4..a699835849 100644 --- a/src/parse/index.js +++ b/src/parse/index.js @@ -5,6 +5,7 @@ import toDate from '../toDate/index.js' import subMilliseconds from '../subMilliseconds/index.js' import defaultLocale from '../locale/en-US/index.js' import parsers from './_lib/parsers/index.js' +import longFormatters from '../_lib/format/longFormatters/index.js' import { isProtectedWeekYearToken, isProtectedDayOfYearToken, @@ -26,6 +27,10 @@ var TIMEZONE_UNIT_PRIORITY = 10 // - . matches any single character unmatched by previous parts of the RegExps var formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g +// This RegExp catches symbols escaped by quotes, and also +// sequences of symbols P, p, and the combinations like `PPPPPPPppppp` +var longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g + var escapedStringRegExp = /^'(.*?)'?$/ var doubleQuoteRegExp = /''/g @@ -186,6 +191,16 @@ var unescapedLatinCharacterRegExp = /[a-zA-Z]/ * | | | xxx | -08:00, +05:30, +00:00 | 2 | * | | | xxxx | -0800, +0530, +0000, +123456 | | * | | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | | + * | Long localized date | NA | P | 05/29/1453 | 5,8 | + * | | | PP | May 29, 1453 | | + * | | | PPP | May 29th, 1453 | | + * | | | PPPP | Sunday, May 29th, 1453 | 2,5,8 | + * | Long localized time | NA | p | 12:00 AM | 5,8 | + * | | | pp | 12:00:00 AM | | + * | Combination of date and time | NA | Pp | 05/29/1453, 12:00 AM | | + * | | | PPpp | May 29, 1453, 12:00:00 AM | | + * | | | PPPpp | May 29th, 1453 at ... | | + * | | | PPPPpp | Sunday, May 29th, 1453 at ... | 2,5,8 | * Notes: * 1. "Formatting" units (e.g. formatting quarter) in the default en-US locale * are the same as "stand-alone" units, but are different in some languages. @@ -240,6 +255,8 @@ var unescapedLatinCharacterRegExp = /[a-zA-Z]/ * - `I`: ISO week of year * - `R`: ISO week-numbering year * - `o`: ordinal number modifier + * - `P`: long localized date + * - `p`: long localized time * * 6. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years. * You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://git.io/fxCyr @@ -247,6 +264,14 @@ var unescapedLatinCharacterRegExp = /[a-zA-Z]/ * 7. `D` and `DD` tokens represent days of the year but they are ofthen confused with days of the month. * You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://git.io/fxCyr * + * 8. `P+` tokens do not have a defined priority since they are merely aliases to other tokens based + * on the given locale. + * + * using `en-US` locale: `P` => `MM/dd/yyyy` + * using `en-US` locale: `p` => `hh:mm a` + * using `pt-BR` locale: `P` => `dd/MM/yyyy` + * using `pt-BR` locale: `p` => `HH:mm` + * * Values will be assigned to the date in the descending order of its unit's priority. * Units of an equal priority overwrite each other in the order of appearance. * @@ -397,7 +422,18 @@ export default function parse( var i - var tokens = formatString.match(formattingTokensRegExp) + var tokens = formatString + .match(longFormattingTokensRegExp) + .map(function(substring) { + var firstCharacter = substring[0] + if (firstCharacter === 'p' || firstCharacter === 'P') { + var longFormatter = longFormatters[firstCharacter] + return longFormatter(substring, locale.formatLong, subFnOptions) + } + return substring + }) + .join('') + .match(formattingTokensRegExp) for (i = 0; i < tokens.length; i++) { var token = tokens[i] diff --git a/src/parse/test.js b/src/parse/test.js index 13a884466d..edd57b8b56 100644 --- a/src/parse/test.js +++ b/src/parse/test.js @@ -1555,4 +1555,131 @@ describe('parse', function() { assert.deepEqual(result, new Date(2015, 10, 5)) }) }) + + describe('long format', function() { + it('short date', function() { + var expected = new Date(1995, 4 /* May */, 26) + var dateString = '05/26/1995' + var formatString = 'P' + var result = parse(dateString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('medium date', function() { + var expected = new Date(1995, 4 /* May */, 26) + var dateString = 'May 26, 1995' + var formatString = 'PP' + var result = parse(dateString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('long date', function() { + var expected = new Date(1995, 4 /* May */, 26) + var dateString = 'May 26th, 1995' + var formatString = 'PPP' + var result = parse(dateString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('full date', function() { + var expected = new Date(1995, 4 /* May */, 26) + var dateString = 'Friday, May 26th, 1995' + var formatString = 'PPPP' + var result = parse(dateString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('short time', function() { + var expected = new Date( + baseDate.getFullYear(), + baseDate.getMonth(), + baseDate.getDate(), + 10, + 32 + ) + var timeString = '10:32 AM' + var formatString = 'p' + var result = parse(timeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('medium time', function() { + var expected = new Date( + baseDate.getFullYear(), + baseDate.getMonth(), + baseDate.getDate(), + 10, + 32, + 55 + ) + var timeString = '10:32:55 AM' + var formatString = 'pp' + var result = parse(timeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('short date + short time', function() { + var expected = new Date(1995, 4 /* May */, 26, 10, 32) + var dateTimeString = '05/26/1995, 10:32 AM' + var formatString = 'Pp' + var result = parse(dateTimeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('medium date + short time', function() { + var expected = new Date(1995, 4 /* May */, 26, 10, 32) + var dateTimeString = 'May 26, 1995, 10:32 AM' + var formatString = 'PPp' + var result = parse(dateTimeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('long date + short time', function() { + var expected = new Date(1995, 4 /* May */, 26, 10, 32) + var dateTimeString = 'May 26th, 1995 at 10:32 AM' + var formatString = 'PPPp' + var result = parse(dateTimeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('full date + short time', function() { + var expected = new Date(1995, 4 /* May */, 26, 10, 32) + var dateTimeString = 'Friday, May 26th, 1995 at 10:32 AM' + var formatString = 'PPPPp' + var result = parse(dateTimeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('short date + short time', function() { + var expected = new Date(1995, 4 /* May */, 26, 10, 32, 55) + var dateTimeString = '05/26/1995, 10:32:55 AM' + var formatString = 'Ppp' + var result = parse(dateTimeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('medium date + short time', function() { + var expected = new Date(1995, 4 /* May */, 26, 10, 32, 55) + var dateTimeString = 'May 26, 1995, 10:32:55 AM' + var formatString = 'PPpp' + var result = parse(dateTimeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('long date + short time', function() { + var expected = new Date(1995, 4 /* May */, 26, 10, 32, 55) + var dateTimeString = 'May 26th, 1995 at 10:32:55 AM' + var formatString = 'PPPpp' + var result = parse(dateTimeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + + it('full date + short time', function() { + var expected = new Date(1995, 4 /* May */, 26, 10, 32, 55) + var dateTimeString = 'Friday, May 26th, 1995 at 10:32:55 AM' + var formatString = 'PPPPpp' + var result = parse(dateTimeString, formatString, baseDate) + assert.deepEqual(result, expected) + }) + }) }) diff --git a/yarn.lock b/yarn.lock index e4851e68f3..2de19d0f84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2957,7 +2957,7 @@ csso@^3.5.0: dependencies: css-tree "1.0.0-alpha.29" -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": +"cssom@>= 0.3.2 < 0.4.0": version "0.3.6" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad" integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A== @@ -3592,11 +3592,6 @@ esprima@2.7.x, esprima@^2.7.1: resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= -esprima@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= - esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"