@@ -27,7 +27,7 @@ define([
2727 */
2828
2929return function ( options , cldr ) {
30- var dateSkeleton , result , skeleton , timeSkeleton , type ;
30+ var dateSkeleton , result , skeleton , timeSkeleton , type , dateTimeSkeleton ;
3131
3232 function combineDateTime ( type , datePattern , timePattern ) {
3333 return formatMessage (
@@ -56,9 +56,13 @@ return function( options, cldr ) {
5656 } ) ;
5757 }
5858
59- ratedFormats . sort ( function ( formatA , formatB ) {
60- return formatA . rate - formatB . rate ;
61- } ) ;
59+ ratedFormats = ratedFormats
60+ . filter ( function ( format ) {
61+ return format . rate > - 1 ;
62+ } )
63+ . sort ( function ( formatA , formatB ) {
64+ return formatA . rate - formatB . rate ;
65+ } ) ;
6266
6367 if ( ratedFormats . length ) {
6468 pattern = augmentFormat ( skeleton , ratedFormats [ 0 ] . pattern ) ;
@@ -68,64 +72,93 @@ return function( options, cldr ) {
6872 return pattern ;
6973 }
7074
71- function compareFormats ( formatA , formatB ) {
72- var distance , maxLength , minLength , index ;
75+ function repeatStr ( str , count ) {
76+ var i , result = "" ;
77+ for ( i = 0 ; i < count ; i ++ ) {
78+ result = result + str ;
79+ }
80+ return result ;
81+ }
7382
74- maxLength = Math . max ( formatA . length , formatB . length ) ;
75- minLength = Math . min ( formatA . length , formatB . length ) ;
76- distance = maxLength / minLength ;
83+ function normalizePatternType ( char ) {
84+ switch ( char ) {
85+ case "e" :
86+ case "E" :
87+ case "c" :
88+ return "e" ;
7789
78- formatA = formatA . match ( datePatternRe ) ;
79- formatB = formatB . match ( datePatternRe ) ;
80- maxLength = Math . max ( formatA . length , formatB . length ) ;
81- minLength = Math . min ( formatA . length , formatB . length ) ;
90+ case "M" :
91+ case "L" :
92+ return "L" ;
8293
83- for ( index = 0 ; index < minLength ; index ++ ) {
84- if ( formatA [ index ] . charAt ( 0 ) === formatB [ index ] . charAt ( 0 ) ) {
85- if ( formatA [ index ] . length === formatB [ index ] . length ) {
86- distance *= 0.25 ;
87- } else {
88- distance *= 0.75 ;
89- }
90- } else {
91- distance *= 1.25 ;
92- }
94+ default :
95+ return char ;
9396 }
97+ }
9498
95- distance *= 1.25 * ( maxLength - minLength + 1 ) ;
99+ function compareFormats ( formatA , formatB ) {
100+ var distance ,
101+ typeA ,
102+ typeB ,
103+ matchFound ,
104+ i ,
105+ j ;
106+
107+ if ( formatA === formatB ) {
108+ return 0 ;
109+ }
96110
111+ formatA = formatA . match ( datePatternRe ) ;
112+ formatB = formatB . match ( datePatternRe ) ;
97113 if ( formatA . length === formatB . length ) {
98- distance *= 0.5 ;
114+ distance = 1 ;
115+ for ( i = 0 ; i < formatA . length ; i ++ ) {
116+ typeA = normalizePatternType ( formatA [ i ] . charAt ( 0 ) ) ;
117+ typeB = null ;
118+ matchFound = false ;
119+ for ( j = 0 ; j < formatB . length ; j ++ ) {
120+ typeB = normalizePatternType ( formatB [ j ] . charAt ( 0 ) ) ;
121+ if ( typeA === typeB ) {
122+ break ;
123+ } else {
124+ typeB = null ;
125+ }
126+ }
127+ if ( null === typeB ) {
128+ return - 1 ;
129+ }
130+ distance = distance + Math . abs ( formatA [ i ] . length - formatB [ j ] . length ) ;
131+ if ( formatA [ i ] . charAt ( 0 ) !== formatB [ j ] . charAt ( 0 ) ) {
132+ distance = distance + 1 ;
133+ }
134+ }
135+ return distance ;
99136 }
100-
101- return distance ;
137+ return - 1 ;
102138 }
103139
104140 function augmentFormat ( requestedSkeleton , bestMatchFormat ) {
105- var originalBestMatchFormat , index , type , tempIndex ;
141+ var i , j , matchedType , matchedLength , requestedType , requestedLength ;
106142
107- originalBestMatchFormat = bestMatchFormat ;
108143 requestedSkeleton = requestedSkeleton . match ( datePatternRe ) ;
109144 bestMatchFormat = bestMatchFormat . match ( datePatternRe ) ;
110145
111- for ( index in bestMatchFormat ) {
112- type = bestMatchFormat [ index ] . charAt ( 0 ) ;
113-
114- for ( tempIndex in requestedSkeleton ) {
115- if ( type === requestedSkeleton [ tempIndex ] . charAt ( 0 ) ) {
116- bestMatchFormat [ index ] = requestedSkeleton [ tempIndex ] ;
117- break ;
146+ for ( i = 0 ; i < bestMatchFormat . length ; i ++ ) {
147+ matchedType = bestMatchFormat [ i ] . charAt ( 0 ) ;
148+ matchedLength = bestMatchFormat [ i ] . length ;
149+ for ( j = 0 ; j < requestedSkeleton . length ; j ++ ) {
150+ requestedType = requestedSkeleton [ j ] . charAt ( 0 ) ;
151+ requestedLength = requestedSkeleton [ j ] . length ;
152+ if (
153+ normalizePatternType ( matchedType ) === normalizePatternType ( requestedType ) &&
154+ matchedLength < requestedLength
155+ ) {
156+ bestMatchFormat [ i ] = repeatStr ( matchedType , requestedLength ) ;
118157 }
119158 }
120159 }
121160
122- bestMatchFormat = bestMatchFormat . join ( "" ) ;
123-
124- if ( bestMatchFormat === originalBestMatchFormat ) {
125- bestMatchFormat = requestedSkeleton . join ( "" ) ;
126- }
127-
128- return bestMatchFormat ;
161+ return bestMatchFormat . join ( "" ) ;
129162 }
130163
131164 switch ( true ) {
@@ -138,28 +171,37 @@ return function( options, cldr ) {
138171 if ( ! result ) {
139172 timeSkeleton = skeleton . split ( / [ ^ h H K k m s S A z Z O v V X x ] / ) . slice ( - 1 ) [ 0 ] ;
140173 dateSkeleton = skeleton . split ( / [ ^ G y Y u U r Q q M L l w W d D F g E e c ] / ) [ 0 ] ;
141- if ( / ( M M M M | L L L L ) .* [ E c ] / . test ( dateSkeleton ) ) {
142- type = "full" ;
143- } else if ( / M M M M / g. test ( dateSkeleton ) ) {
144- type = "long" ;
145- } else if ( / M M M / g. test ( dateSkeleton ) || / L L L / g. test ( dateSkeleton ) ) {
146- type = "medium" ;
147- } else {
148- type = "short" ;
149- }
150- dateSkeleton = getBestMatchPattern (
174+ dateTimeSkeleton = getBestMatchPattern (
151175 "dates/calendars/gregorian/dateTimeFormats/availableFormats" ,
152- dateSkeleton
176+ skeleton
153177 ) ;
154- timeSkeleton = getBestMatchPattern (
155- "dates/calendars/gregorian/dateTimeFormats/availableFormats" ,
156- timeSkeleton
157- ) ;
158-
159- if ( dateSkeleton && timeSkeleton ) {
160- result = combineDateTime ( type , dateSkeleton , timeSkeleton ) ;
178+ if ( dateTimeSkeleton ) {
179+ result = dateTimeSkeleton ;
161180 } else {
162- result = dateSkeleton || timeSkeleton ;
181+ dateSkeleton = getBestMatchPattern (
182+ "dates/calendars/gregorian/dateTimeFormats/availableFormats" ,
183+ dateSkeleton
184+ ) ;
185+ timeSkeleton = getBestMatchPattern (
186+ "dates/calendars/gregorian/dateTimeFormats/availableFormats" ,
187+ timeSkeleton
188+ ) ;
189+
190+ if ( / ( M M M M | L L L L ) .* [ E c ] / . test ( dateSkeleton ) ) {
191+ type = "full" ;
192+ } else if ( / M M M M / g. test ( dateSkeleton ) ) {
193+ type = "long" ;
194+ } else if ( / M M M / g. test ( dateSkeleton ) || / L L L / g. test ( dateSkeleton ) ) {
195+ type = "medium" ;
196+ } else {
197+ type = "short" ;
198+ }
199+
200+ if ( dateSkeleton && timeSkeleton ) {
201+ result = combineDateTime ( type , dateSkeleton , timeSkeleton ) ;
202+ } else {
203+ result = dateSkeleton || timeSkeleton ;
204+ }
163205 }
164206 }
165207 break ;
0 commit comments