public List < Node > parse ( String raw ) { // holds literal text as we parse StringBuilder buf = new StringBuilder ( ) ; // current field character, \0 if none char field = ' ' ; // current field width int width = 0 ; // flag indicating we're inside a literal string boolean inquote = false ; // length of input pattern int length = raw . length ( ) ; // current input pattern index int i = 0 ; List < Node > nodes = new ArrayList <> ( ) ; while ( i < length ) { char ch = raw . charAt ( i ) ; // Handle appending / terminating the single-quote delimited sequence. if ( inquote ) { if ( ch == ' ' ) { inquote = false ; field = ' ' ; } else { buf . append ( ch ) ; } i ++ ; continue ; } switch ( ch ) { // Date pattern field characters. case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : case ' ' : // Before we start this field, check if we have text to push. if ( buf . length ( ) > 0 ) { nodes . add ( new Text ( buf . toString ( ) ) ) ; buf . setLength ( 0 ) ; } // A change in character indicates we're starting a new field; // otherwise we're widening an existing field. if ( ch != field ) { // If we have a field defined, add it. if ( field != ' ' ) { nodes . add ( new Field ( field , width ) ) ; } // Start a new field. field = ch ; width = 1 ; } else { // Widen the current field. width ++ ; } // Indicate we've started a new field. break ; default : // If we have a current field, add it. if ( field != ' ' ) { nodes . add ( new Field ( field , width ) ) ; } // Clear the field. field = ' ' ; // Single quotes escape literal characters used for field patterns. if ( ch == ' ' ) { inquote = true ; } else { // Append a character buf . append ( ch ) ; } break ; } i ++ ; } if ( width > 0 && field != ' ' ) { nodes . add ( new Field ( field , width ) ) ; } else if ( buf . length ( ) > 0 ) { nodes . add ( new Text ( buf . toString ( ) ) ) ; } return nodes ; }
Parses a CLDR date - time pattern into a series of Text and Field nodes .