in src/main/java/com/aliyun/dts/subscribe/clients/record/value/DateTime.java [432:622]
Triple<Boolean, StringBuilder, StringBuilder> validateAndConvertTimeZone(String timeZone) {
if (StringUtils.isEmpty(timeZone)) {
return Triple.of(false, null, null);
}
char charValue;
boolean isLegalTimeZone = false;
int index = 0;
final int totalLength = timeZone.length();
final StringBuilder sbl = new StringBuilder(16);
final StringBuilder tzSbl = new StringBuilder(16);
charValue = timeZone.charAt(index);
check_and_fix:
{
// check first letter
switch (charValue) {
case 'G':
if ('M' != timeZone.charAt(++index)) {
break check_and_fix;
}
if ('T' != timeZone.charAt(++index)) {
break check_and_fix;
}
tzSbl.append("GMT");
++index;
break;
case 'U':
// short path for UTC
if ('T' != timeZone.charAt(++index)) {
break check_and_fix;
}
if ('C' != timeZone.charAt(++index)) {
break check_and_fix;
}
tzSbl.append("UTC");
++index;
break;
case '+':
case '-':
// add default timezone specification
tzSbl.append("GMT");
break;
default:
if ('0' <= charValue && '9' >= charValue) {
tzSbl.append("GMT");
break;
} else {
final String tmpOffset = timeZoneOffsets.getOrDefault(timeZone.toLowerCase(), null);
if (null == tmpOffset) {
break check_and_fix;
} else {
// special time zone, convert it to time offset
isLegalTimeZone = true;
sbl.append(tmpOffset);
tzSbl.append(timeZone);
break check_and_fix;
}
}
}
// check remaining letters
/**
* we use a state machine to do the checking and fixing:
*
* SUCCESS_FIN <---| <-----------------|
* ^ | |
* e| |e |e
* 0~9 | 0~9 | : 0~9 | 0~9 : 0~9 0~9 e
* 0 --------> 1 ----------> 2 --------> 3 ------> 4 ------> 5 ------> 6 -------> 7 ------> 8 ------> 9 ----> SUCCESS_FIN
* | | | ^
* | | | : |
* | | |---------------|
* | |
* | others V
* |--------------> ERROR_FIN
*/
int processingState = 0;
while (index < totalLength) {
charValue = timeZone.charAt(index++);
switch (processingState) {
case 0:
if (' ' == charValue) {
processingState = 0;
} else if ('+' == charValue || '-' == charValue) {
sbl.append(charValue);
processingState = 1;
} else if ('0' <= charValue && '9' >= charValue) {
sbl.append("+");
sbl.append(charValue);
processingState = 2;
} else {
break check_and_fix;
}
break;
case 1:
if ('0' <= charValue && '9' >= charValue) {
sbl.append(charValue);
processingState = 2;
} else {
break check_and_fix;
}
break;
case 2:
if ('0' <= charValue && '9' >= charValue) {
sbl.append(charValue);
processingState = 3;
} else if (':' == charValue) {
sbl.insert(sbl.length() - 1, '0');
sbl.append(charValue);
processingState = 4;
} else {
break check_and_fix;
}
break;
case 3:
if (':' == charValue) {
sbl.append(charValue);
processingState = 4;
} else {
break check_and_fix;
}
break;
case 4:
if ('0' <= charValue && '9' >= charValue) {
sbl.append(charValue);
processingState = 5;
} else {
break check_and_fix;
}
break;
case 5:
if ('0' <= charValue && '9' >= charValue) {
sbl.append(charValue);
processingState = 6;
} else {
break check_and_fix;
}
break;
case 6:
if (':' == charValue) {
processingState = 7;
sbl.append(charValue);
} else {
break check_and_fix;
}
break;
case 7:
if ('0' <= charValue && '9' >= charValue) {
sbl.append(charValue);
processingState = 8;
} else {
break check_and_fix;
}
break;
case 8:
if ('0' <= charValue && '9' >= charValue) {
sbl.append(charValue);
processingState = 9;
} else {
break check_and_fix;
}
break;
default:
break check_and_fix;
}
}
// here we process the e input for state
switch (processingState) {
case 0:
sbl.append('+');
sbl.append('0');
case 2:
sbl.insert(sbl.length() - 1, '0');
case 3:
sbl.append(":00");
tzSbl.append(sbl);
isLegalTimeZone = true;
break;
case 5:
case 8:
sbl.insert(sbl.length() - 1, '0');
case 6:
case 9:
tzSbl.append(sbl);
isLegalTimeZone = true;
break;
}
}
return Triple.of(isLegalTimeZone, sbl, tzSbl);
}