Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
reimplements globalizejs#462
  • Loading branch information
Strate committed Mar 22, 2016
1 parent ab67520 commit e107ff6
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 11 deletions.
116 changes: 105 additions & 11 deletions src/date/expand-pattern.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
define([
"../common/format-message",
"../common/create-error/invalid-parameter-value"
], function( formatMessage, createErrorInvalidParameterValue ) {
"../common/create-error/invalid-parameter-value",
"./pattern-re"
], function( formatMessage, createErrorInvalidParameterValue, datePatternRe ) {

/**
* expandPattern( options, cldr )
Expand Down Expand Up @@ -38,6 +39,95 @@ return function( options, cldr ) {
);
}

function getBestMatchPattern( path, skeleton ) {
var availableFormats, ratedFormats, format, pattern;

pattern = cldr.main([ path, skeleton ]);

if ( skeleton && !pattern ) {
availableFormats = cldr.main([ path ]);
ratedFormats = [];

for ( format in availableFormats ) {
ratedFormats.push({
format: format,
pattern: availableFormats[format],
rate: compareFormats( skeleton, format )
});
}

ratedFormats.sort( function( formatA, formatB ) {
return formatA.rate - formatB.rate;
});

if ( ratedFormats.length ) {
pattern = augmentFormat( skeleton, ratedFormats[0].pattern );
}
}

return pattern;
}

function compareFormats( formatA, formatB ) {
var distance, maxLength, minLength, index;

maxLength = Math.max( formatA.length, formatB.length );
minLength = Math.min( formatA.length, formatB.length );
distance = maxLength / minLength;

formatA = formatA.match( datePatternRe );
formatB = formatB.match( datePatternRe );
maxLength = Math.max( formatA.length, formatB.length );
minLength = Math.min( formatA.length, formatB.length );

for ( index = 0; index < minLength; index++ ) {
if ( formatA[index].charAt( 0 ) === formatB[index].charAt( 0 ) ) {
if ( formatA[index].length === formatB[index].length ) {
distance *= 0.25;
} else {
distance *= 0.75;
}
} else {
distance *= 1.25;
}
}

distance *= 1.25 * ( maxLength - minLength + 1 );

if ( formatA.length === formatB.length ) {
distance *= 0.5;
}

return distance;
}

function augmentFormat( requestedSkeleton, bestMatchFormat ) {
var originalBestMatchFormat, index, type, tempIndex;

originalBestMatchFormat = bestMatchFormat;
requestedSkeleton = requestedSkeleton.match( datePatternRe );
bestMatchFormat = bestMatchFormat.match( datePatternRe );

for ( index in bestMatchFormat ) {
type = bestMatchFormat[index].charAt( 0 );

for ( tempIndex in requestedSkeleton ) {
if ( type === requestedSkeleton[tempIndex].charAt( 0 ) ) {
bestMatchFormat[index] = requestedSkeleton[tempIndex];
break;
}
}
}

bestMatchFormat = bestMatchFormat.join( "" );

if ( bestMatchFormat === originalBestMatchFormat ) {
bestMatchFormat = requestedSkeleton.join( "" );
}

return bestMatchFormat;
}

switch ( true ) {
case "skeleton" in options:
skeleton = options.skeleton;
Expand All @@ -57,16 +147,20 @@ return function( options, cldr ) {
} else {
type = "short";
}
result = combineDateTime( type,
cldr.main([
"dates/calendars/gregorian/dateTimeFormats/availableFormats",
dateSkeleton
]),
cldr.main([
"dates/calendars/gregorian/dateTimeFormats/availableFormats",
timeSkeleton
])
dateSkeleton = getBestMatchPattern(
"dates/calendars/gregorian/dateTimeFormats/availableFormats",
dateSkeleton
);
timeSkeleton = getBestMatchPattern(
"dates/calendars/gregorian/dateTimeFormats/availableFormats",
timeSkeleton
);

if ( dateSkeleton && timeSkeleton ) {
result = combineDateTime( type, dateSkeleton, timeSkeleton );
} else {
result = dateSkeleton || timeSkeleton;
}
}
break;

Expand Down
9 changes: 9 additions & 0 deletions test/functional/date/date-formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,13 @@ QUnit.test( "should allow for runtime compilation", function( assert ) {

});

QUnit.test( "should augment a skeleton", function( assert ) {
extraSetup();

assert.equal( Globalize.dateFormatter({ skeleton: "yMMMMd" })( date ), "September 15, 2010" );
assert.equal( Globalize.dateFormatter({ skeleton: "MMMMd" })( date ), "September 15" );
assert.equal( Globalize.dateFormatter({ skeleton: "MMMM" })( date ), "September" );
assert.equal( Globalize.dateFormatter({ skeleton: "EEEE" })( date ), "Wednesday" );
});

});
7 changes: 7 additions & 0 deletions test/unit/date/expand-pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,11 @@ QUnit.test( "should expand {raw: \"<pattern>\"}", function( assert ) {
assert.equal( expandPattern( { raw: "MMM d" }, en ), "MMM d" );
});

QUnit.test( "should augment {skeleton: \"<skeleton>\"}", function( assert ) {
assert.equal( expandPattern( { skeleton: "yMMMMd" }, de ), "d. MMMM y" );
assert.equal( expandPattern( { skeleton: "MMMMd" }, de ), "d. MMMM" );
assert.equal( expandPattern( { skeleton: "MMMM" }, de ), "MMMM" );
assert.equal( expandPattern( { skeleton: "EEEE" }, de ), "EEEE" );
});

});

0 comments on commit e107ff6

Please sign in to comment.