@@ -2204,7 +2204,18 @@ function ToDateTimeOptions (options, required, defaults) {
2204
2204
* formats, the following steps are taken:
2205
2205
*/
2206
2206
function BasicFormatMatcher ( options , formats ) {
2207
+ return calculateScore ( options , formats ) ;
2208
+ }
2209
+
2210
+ /**
2211
+ * Calculates score for BestFitFormatMatcher and BasicFormatMatcher.
2212
+ * Abstracted from BasicFormatMatcher section.
2213
+ */
2214
+ function calculateScore ( options , formats , bestFit ) {
2207
2215
var
2216
+ // Additional penalty type when bestFit === true
2217
+ diffDataTypePenalty = 8 ,
2218
+
2208
2219
// 1. Let removalPenalty be 120.
2209
2220
removalPenalty = 120 ,
2210
2221
@@ -2256,7 +2267,7 @@ function BasicFormatMatcher (options, formats) {
2256
2267
// ii. Let formatPropDesc be the result of calling the [[GetOwnProperty]] internal method of format
2257
2268
// with argument property.
2258
2269
// iii. If formatPropDesc is not undefined, then
2259
- // 1. Let formatProp be the result of calling the [[Get]] internal method of format with argument property.
2270
+ // 1. Let formatProp be the result of calling the [[Get]] internal method of format with argument property.
2260
2271
formatProp = hop . call ( format , property ) ? format [ property ] : undefined ;
2261
2272
2262
2273
// iv. If optionsProp is undefined and formatProp is not undefined, then decrease score by
@@ -2285,6 +2296,13 @@ function BasicFormatMatcher (options, formats) {
2285
2296
// 4. Let delta be max(min(formatPropIndex - optionsPropIndex, 2), -2).
2286
2297
delta = Math . max ( Math . min ( formatPropIndex - optionsPropIndex , 2 ) , - 2 ) ;
2287
2298
2299
+ // When the bestFit argument is true, subtract additional penalty where data types are not the same
2300
+ if ( bestFit && (
2301
+ ( ( optionsProp === 'numeric' || optionsProp === '2-digit' ) && ( formatProp !== 'numeric' && formatProp !== '2-digit' ) )
2302
+ || ( ( optionsProp !== 'numeric' && optionsProp !== '2-digit' ) && ( formatProp === '2-digit' || formatProp === 'numeric' ) )
2303
+ ) )
2304
+ score -= diffDataTypePenalty ;
2305
+
2288
2306
// 5. If delta = 2, decrease score by longMorePenalty.
2289
2307
if ( delta === 2 )
2290
2308
score -= longMorePenalty ;
@@ -2325,10 +2343,28 @@ function BasicFormatMatcher (options, formats) {
2325
2343
* and formats, it performs implementation dependent steps, which should return a set of
2326
2344
* component representations that a typical user of the selected locale would perceive as
2327
2345
* at least as good as the one returned by BasicFormatMatcher.
2346
+ *
2347
+ * This polyfill defines the algorithm to be the same as BasicFormatMatcher,
2348
+ * with the addition of bonus points awarded where the requested format is of
2349
+ * the same data type as the potentially matching format.
2350
+ *
2351
+ * For example,
2352
+ *
2353
+ * { month: 'numeric', day: 'numeric' }
2354
+ *
2355
+ * should match
2356
+ *
2357
+ * { month: '2-digit', day: '2-digit' }
2358
+ *
2359
+ * rather than
2360
+ *
2361
+ * { month: 'short', day: 'numeric' }
2362
+ *
2363
+ * This makes sense because a user requesting a formatted date with numeric parts would
2364
+ * not expect to see the returned format containing narrow, short or long part names
2328
2365
*/
2329
2366
function BestFitFormatMatcher ( options , formats ) {
2330
- // This is good enough for now
2331
- return BasicFormatMatcher ( options , formats ) ;
2367
+ return calculateScore ( options , formats , true ) ;
2332
2368
}
2333
2369
2334
2370
/* 12.2.3 */ internals . DateTimeFormat = {
0 commit comments