public static int parseTimeOfDay()

in util/src/main/java/com/epam/deltix/util/time/TimeFormatter.java [376:567]


    public static int parseTimeOfDay (CharSequence text)
        throws TimeOfDayParseException
    {
        /// See test.td.util.time.Test_SimpleTimeOfDayFormat for JUnit test of this method

        final int len = (text != null) ? text.length() : 0;

        if (len == 0)
            throw new TimeOfDayParseException ("Cannot parse empty string as time of day", text, 0);

        int pos = 0;
        int hours = 0, minutes = 0, seconds = 0;

        // BEGIN(Good old C mode)
        final int TERMINAL_STATE_MASK                 = 0x100;
        final int STATE_EXPECT_FIRST_HOUR_DIGIT       = 0x001; // non terminal
        final int STATE_PARSED_FIRST_HOUR_DIGIT       = 0x102;
        final int STATE_PARSED_BOTH_HOUR_DIGITS       = 0x103;
        final int STATE_EXPECT_FIRST_MINUTE_DIGIT     = 0x004; // non terminal
        final int STATE_PARSED_FIRST_MINUTE_DIGIT     = 0x105;
        final int STATE_PARSED_BOTH_MINUTE_DIGITS     = 0x106;
        final int STATE_EXPECT_FIRST_SECOND_DIGIT     = 0x007; // non terminal
        final int STATE_PARSED_FIRST_SECONDS_DIGIT    = 0x108;
        final int STATE_PARSED_BOTH_SECOND_DIGITS     = 0x109;
        final int STATE_PARSED_SPACE                  = 0x00A; // non terminal
        final int STATE_EXPECT_M_SYMBOL               = 0x00B; // non terminal
        final int STATE_PARSED_M_SYMBOL               = 0x10C;

        int state = STATE_EXPECT_FIRST_HOUR_DIGIT;

        while (pos < len) {
            final char ch = text.charAt (pos);

            switch (state) {
                // initial state
                case STATE_EXPECT_FIRST_HOUR_DIGIT:
                    if (ch >= '0' && ch <= '9') {
                        hours = (ch - '0');
                        state = STATE_PARSED_FIRST_HOUR_DIGIT;
                    } else {
                        throw new TimeOfDayParseException ("Expecting first hour digit", text, pos);
                    }
                    break;

                // we parsed first digit of hours value
                case STATE_PARSED_FIRST_HOUR_DIGIT:
                    if (ch >= '0' && ch <= '9') {
                        hours = hours * 10 + (ch - '0');
                        if (hours > 23)
                            throw new TimeOfDayParseException ("Hours value exceed 23", text, pos);
                        state = STATE_PARSED_BOTH_HOUR_DIGITS;
                    } else if (ch == ':') {
                        state = STATE_EXPECT_FIRST_MINUTE_DIGIT;
                    } else if (ch == ' ' || ch == '\t') {
                        state = STATE_PARSED_SPACE;
                    } else {
                        throw new TimeOfDayParseException ("Unexpected hours separator '" + ch + "'", text, pos);
                    }
                    break;

                // we parsed two digits of hours value
                case STATE_PARSED_BOTH_HOUR_DIGITS:
                    if (ch == ':') {
                        state = STATE_EXPECT_FIRST_MINUTE_DIGIT;
                    } else if (ch == ' ' || ch == '\t') {
                        state = STATE_PARSED_SPACE;
                    } else {
                        throw new TimeOfDayParseException ("Unexpected hours separator '" + ch + "'", text, pos);
                    }
                    break;

                // we parsed first ':' symbol
                case STATE_EXPECT_FIRST_MINUTE_DIGIT:
                    if (ch >= '0' && ch <= '9') {
                        minutes = (ch - '0');
                        state = STATE_PARSED_FIRST_MINUTE_DIGIT;
                    } else {
                        throw new TimeOfDayParseException ("Expecting first minutes digit", text, pos);
                    }
                    break;

                // we parsed first digit of minutes value
                case STATE_PARSED_FIRST_MINUTE_DIGIT:
                    if (ch >= '0' && ch <= '9') {
                        minutes = minutes * 10 + (ch - '0');
                        if (minutes > 59)
                            throw new TimeOfDayParseException ("Minutes value exceed 59", text, pos);
                        state = STATE_PARSED_BOTH_MINUTE_DIGITS;
                    } else if (ch == ':') {
                        state = STATE_EXPECT_FIRST_SECOND_DIGIT;
                    } else if (ch == ' ' || ch == '\t') {
                        state = STATE_PARSED_SPACE;
                    } else {
                        throw new TimeOfDayParseException ("Unexpected minutes separator '" + ch + "'", text, pos);
                    }
                    break;

                // we parsed two digits of minutes value
                case STATE_PARSED_BOTH_MINUTE_DIGITS:
                    if (ch == ':') {
                        state = STATE_EXPECT_FIRST_SECOND_DIGIT;
                    } else if (ch == ' ' || ch == '\t') {
                        state = STATE_PARSED_SPACE;
                    } else {
                        throw new TimeOfDayParseException ("Unexpected minutes separator '" + ch + "'", text, pos);
                    }
                    break;

                // we parsed second ':' symbol
                case STATE_EXPECT_FIRST_SECOND_DIGIT:
                    if (ch >= '0' && ch <= '9') {
                        seconds = (ch - '0');
                        state = STATE_PARSED_FIRST_SECONDS_DIGIT;
                    } else {
                        throw new TimeOfDayParseException ("Expecting first seconds digit", text, pos);
                    }
                    break;

                // we parsed first digit of seconds value
                case STATE_PARSED_FIRST_SECONDS_DIGIT:
                    if (ch >= '0' && ch <= '9') {
                        seconds = seconds * 10 + (ch - '0');
                        if (seconds > 59)
                            throw new TimeOfDayParseException ("Seconds value exceed 59", text, pos);
                        state = STATE_PARSED_BOTH_SECOND_DIGITS;
                    } else if (ch == ' ' || ch == '\t') {
                        state = STATE_PARSED_SPACE;
                    } else {
                        throw new TimeOfDayParseException ("Unexpected character after seconds group '" + ch + "'", text, pos);
                    }
                    break;

                // we parsed two digits of seconds value
                case STATE_PARSED_BOTH_SECOND_DIGITS:
                    if (ch == ' ' || ch == '\t') {
                        state = STATE_PARSED_SPACE;
                    } else {
                        throw new TimeOfDayParseException ("Expecting space separator '" + ch + "'", text, pos);
                    }
                    break;

                // we got space
                case STATE_PARSED_SPACE:
                    if (ch == 'a' || ch == 'A') {
                        if (hours < 1 || hours > 12)
                            throw new TimeOfDayParseException ("Hour in AM/PM format must be [1..12]", text, pos);

                        if (hours == 12)
                            hours = 0;
                        state = STATE_EXPECT_M_SYMBOL;
                    } else if (ch == 'p' || ch == 'P') {
                        if (hours < 1 || hours > 12)
                            throw new TimeOfDayParseException ("Hour in AM/PM format must be [1..12]", text, pos);

                        if (hours != 12)
                            hours += 12;

                        state = STATE_EXPECT_M_SYMBOL;
                    } else if (ch == ' ' || ch == '\t') {
                        state = STATE_PARSED_SPACE;
                    } else {
                        throw new TimeOfDayParseException ("Expecting space or am/pm literal", text, pos);
                    }
                    break;

                case STATE_EXPECT_M_SYMBOL:
                    if (ch == 'm' || ch == 'M') {
                        state = STATE_PARSED_M_SYMBOL;
                        if (++pos < len) // (*)
                            throw new TimeOfDayParseException ("Unexpected tail symbols", text, pos);

                        break;

                    } else {
                        throw new TimeOfDayParseException ("Expecting 'm' symbol", text, pos);
                    }
                case STATE_PARSED_M_SYMBOL: // Redunant with (*)
                    throw new TimeOfDayParseException ("Expected symbol after am/pm: '" + ch + "'", text, pos);

                default:
                    throw new IllegalStateException ("Unexpected state: " + state);

            }
            pos++;
        }

        if ((state & TERMINAL_STATE_MASK) == 0)
            throw new TimeOfDayParseException ("Unexpected end of string (state:" + state +')', text, pos);

        // END(Good old C mode)
        return hours*3600 + minutes*60 + seconds;
    }