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;
}