private static void getDateTimeSkeleton(String skeleton,
                                            StringBuilder dateSkeleton,
                                            StringBuilder normalizedDateSkeleton,
                                            StringBuilder timeSkeleton,
                                            StringBuilder normalizedTimeSkeleton)
    {
        // dateSkeleton follows the sequence of y*M*E*d*
        // timeSkeleton follows the sequence of hm*[v|z]?
        int i;
        int ECount = 0;
        int dCount = 0;
        int MCount = 0;
        int yCount = 0;
        int hCount = 0;
        int HCount = 0;
        int mCount = 0;
        int vCount = 0;
        int zCount = 0;
    
        for (i = 0; i < skeleton.length(); ++i) {
            char ch = skeleton.charAt(i);
            switch ( ch ) {
              case 'E':
                dateSkeleton.append(ch);
                ++ECount;
                break;
              case 'd':
                dateSkeleton.append(ch);
                ++dCount;
                break;
              case 'M':
                dateSkeleton.append(ch);
                ++MCount;
                break;
              case 'y':
                dateSkeleton.append(ch);
                ++yCount;
                break;
              case 'G':
              case 'Y':
              case 'u':
              case 'Q':
              case 'q':
              case 'L':
              case 'l':
              case 'W':
              case 'w':
              case 'D':
              case 'F':
              case 'g':
              case 'e':
              case 'c':
              case 'U':
              case 'r':
                normalizedDateSkeleton.append(ch);
                dateSkeleton.append(ch);
                break;
              case 'a':
                // 'a' is implicitly handled 
                timeSkeleton.append(ch);
                break;
              case 'h':
                timeSkeleton.append(ch);
                ++hCount;
                break;
              case 'H':
                timeSkeleton.append(ch);
                ++HCount;
                break;
              case 'm':
                timeSkeleton.append(ch);
                ++mCount;
                break;
              case 'z':
                ++zCount;
                timeSkeleton.append(ch);
                break;
              case 'v':
                ++vCount;
                timeSkeleton.append(ch);
                break;
              case 'V':
              case 'Z':
              case 'k':
              case 'K':
              case 'j':
              case 's':
              case 'S':
              case 'A':
                timeSkeleton.append(ch);
                normalizedTimeSkeleton.append(ch);
                break;     
            }
        }
    
        /* generate normalized form for date*/
        if ( yCount != 0 ) {
            for (i = 0; i < yCount; i++) {
                normalizedDateSkeleton.append('y');
            }
        }
        if ( MCount != 0 ) {
            if ( MCount < 3 ) {
                normalizedDateSkeleton.append('M');
            } else {
                for ( i = 0; i < MCount && i < 5; ++i ) {
                     normalizedDateSkeleton.append('M');
                }
            }
        }
        if ( ECount != 0 ) {
            if ( ECount <= 3 ) {
                normalizedDateSkeleton.append('E');
            } else {
                for ( i = 0; i < ECount && i < 5; ++i ) {
                     normalizedDateSkeleton.append('E');
                }
            }
        }
        if ( dCount != 0 ) {
            normalizedDateSkeleton.append('d');
        }
    
        /* generate normalized form for time */
        if ( HCount != 0 ) {
            normalizedTimeSkeleton.append('H');
        }
        else if ( hCount != 0 ) {
            normalizedTimeSkeleton.append('h');
        }
        if ( mCount != 0 ) {
            normalizedTimeSkeleton.append('m');
        }
        if ( zCount != 0 ) {
            normalizedTimeSkeleton.append('z');
        }
        if ( vCount != 0 ) {
            normalizedTimeSkeleton.append('v');
        }
    }
private static void getDateTimeSkeleton ( String skeleton , StringBuilder dateSkeleton , StringBuilder normalizedDateSkeleton , StringBuilder timeSkeleton , StringBuilder normalizedTimeSkeleton ) { int i ; int ECount = 0 ; int dCount = 0 ; int MCount = 0 ; int yCount = 0 ; int hCount = 0 ; int HCount = 0 ; int mCount = 0 ; int vCount = 0 ; int zCount = 0 ; for ( i = 0 ; i < skeleton . length ( ) ; ++ i ) { char ch = skeleton . charAt ( i ) ; switch ( ch ) { case 'E' : dateSkeleton . append ( ch ) ; ++ ECount ; break ; case 'd' : dateSkeleton . append ( ch ) ; ++ dCount ; break ; case 'M' : dateSkeleton . append ( ch ) ; ++ MCount ; break ; case 'y' : dateSkeleton . append ( ch ) ; ++ yCount ; break ; case 'G' : case 'Y' : case 'u' : case 'Q' : case 'q' : case 'L' : case 'l' : case 'W' : case 'w' : case 'D' : case 'F' : case 'g' : case 'e' : case 'c' : case 'U' : case 'r' : normalizedDateSkeleton . append ( ch ) ; dateSkeleton . append ( ch ) ; break ; case 'a' : timeSkeleton . append ( ch ) ; break ; case 'h' : timeSkeleton . append ( ch ) ; ++ hCount ; break ; case 'H' : timeSkeleton . append ( ch ) ; ++ HCount ; break ; case 'm' : timeSkeleton . append ( ch ) ; ++ mCount ; break ; case 'z' : ++ zCount ; timeSkeleton . append ( ch ) ; break ; case 'v' : ++ vCount ; timeSkeleton . append ( ch ) ; break ; case 'V' : case 'Z' : case 'k' : case 'K' : case 'j' : case 's' : case 'S' : case 'A' : timeSkeleton . append ( ch ) ; normalizedTimeSkeleton . append ( ch ) ; break ; } } if ( yCount != 0 ) { for ( i = 0 ; i < yCount ; i ++ ) { normalizedDateSkeleton . append ( 'y' ) ; } } if ( MCount != 0 ) { if ( MCount < 3 ) { normalizedDateSkeleton . append ( 'M' ) ; } else { for ( i = 0 ; i < MCount && i < 5 ; ++ i ) { normalizedDateSkeleton . append ( 'M' ) ; } } } if ( ECount != 0 ) { if ( ECount <= 3 ) { normalizedDateSkeleton . append ( 'E' ) ; } else { for ( i = 0 ; i < ECount && i < 5 ; ++ i ) { normalizedDateSkeleton . append ( 'E' ) ; } } } if ( dCount != 0 ) { normalizedDateSkeleton . append ( 'd' ) ; } if ( HCount != 0 ) { normalizedTimeSkeleton . append ( 'H' ) ; } else if ( hCount != 0 ) { normalizedTimeSkeleton . append ( 'h' ) ; } if ( mCount != 0 ) { normalizedTimeSkeleton . append ( 'm' ) ; } if ( zCount != 0 ) { normalizedTimeSkeleton . append ( 'z' ) ; } if ( vCount != 0 ) { normalizedTimeSkeleton . append ( 'v' ) ; } }
/*
get separated date and time skeleton from a combined skeleton.

The difference between date skeleton and normalizedDateSkeleton are:
1. both 'y' and 'd' are appeared only once in normalizeDateSkeleton
2. 'E' and 'EE' are normalized into 'EEE'
3. 'MM' is normalized into 'M'

* the difference between time skeleton and normalizedTimeSkeleton are:
1. both 'H' and 'h' are normalized as 'h' in normalized time skeleton,
2. 'a' is omitted in normalized time skeleton.
3. there is only one appearance for 'h', 'm','v', 'z' in normalized time
skeleton


@param skeleton               given combined skeleton.
@param date                   Output parameter for date only skeleton.
@param normalizedDate         Output parameter for normalized date only

@param time                   Output parameter for time only skeleton.
@param normalizedTime         Output parameter for normalized time only
skeleton.