Skip to content
This repository was archived by the owner on Apr 14, 2021. It is now read-only.

Commit a8010c5

Browse files
committed
Improves BestFitFormatMatcher for DateTimeFormat (fixes #64)
1 parent 4062035 commit a8010c5

File tree

1 file changed

+39
-3
lines changed

1 file changed

+39
-3
lines changed

Intl.js

+39-3
Original file line numberDiff line numberDiff line change
@@ -2204,7 +2204,18 @@ function ToDateTimeOptions (options, required, defaults) {
22042204
* formats, the following steps are taken:
22052205
*/
22062206
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) {
22072215
var
2216+
// Additional penalty type when bestFit === true
2217+
diffDataTypePenalty = 8,
2218+
22082219
// 1. Let removalPenalty be 120.
22092220
removalPenalty = 120,
22102221

@@ -2256,7 +2267,7 @@ function BasicFormatMatcher (options, formats) {
22562267
// ii. Let formatPropDesc be the result of calling the [[GetOwnProperty]] internal method of format
22572268
// with argument property.
22582269
// 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.
22602271
formatProp = hop.call(format, property) ? format[property] : undefined;
22612272

22622273
// iv. If optionsProp is undefined and formatProp is not undefined, then decrease score by
@@ -2285,6 +2296,13 @@ function BasicFormatMatcher (options, formats) {
22852296
// 4. Let delta be max(min(formatPropIndex - optionsPropIndex, 2), -2).
22862297
delta = Math.max(Math.min(formatPropIndex - optionsPropIndex, 2), -2);
22872298

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+
22882306
// 5. If delta = 2, decrease score by longMorePenalty.
22892307
if (delta === 2)
22902308
score -= longMorePenalty;
@@ -2325,10 +2343,28 @@ function BasicFormatMatcher (options, formats) {
23252343
* and formats, it performs implementation dependent steps, which should return a set of
23262344
* component representations that a typical user of the selected locale would perceive as
23272345
* 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
23282365
*/
23292366
function BestFitFormatMatcher (options, formats) {
2330-
// This is good enough for now
2331-
return BasicFormatMatcher(options, formats);
2367+
return calculateScore(options, formats, true);
23322368
}
23332369

23342370
/* 12.2.3 */internals.DateTimeFormat = {

0 commit comments

Comments
 (0)