Add support of ISO 8601 timezone format

This commit is contained in:
Alexey Andreev 2015-05-24 16:47:24 +03:00
parent c8743c6d1f
commit e150e2e44f
2 changed files with 91 additions and 0 deletions

View File

@ -480,6 +480,89 @@ abstract class TDateFormatElement {
} }
} }
public static class Iso8601Timezone extends TDateFormatElement {
private int size;
public Iso8601Timezone(int size) {
this.size = size;
}
@Override
public void format(TCalendar date, StringBuffer buffer) {
int minutes = date.getTimeZone().getOffset(date.getTimeInMillis()) / 60_000;
if (minutes == 0) {
buffer.append('Z');
return;
} else if (minutes > 0) {
buffer.append('+');
} else {
minutes = -minutes;
buffer.append('-');
}
int hours = minutes / 60;
minutes %= 60;
buffer.append(hours / 10).append(hours % 10);
if (size >= 3) {
buffer.append(':');
}
if (size > 1) {
buffer.append(minutes / 10).append(minutes % 10);
}
}
@Override
public void parse(String text, TCalendar date, TParsePosition position) {
int index = position.getIndex();
char signChar = text.charAt(index++);
int sign;
if (signChar == '+') {
sign = 1;
} else if (signChar == '-') {
sign = -1;
} else if (signChar == 'Z') {
date.setTimeZone(TTimeZone.getTimeZone("GMT"));
return;
} else {
position.setErrorIndex(index);
return;
}
int expectedSize = 2;
if (size > 1) {
expectedSize += 2;
}
if (size >= 3) {
++expectedSize;
}
if (index + expectedSize > text.length()) {
position.setErrorIndex(index);
return;
}
if (!Character.isDigit(text.charAt(index)) || !Character.isDigit(text.charAt(index + 1))) {
position.setErrorIndex(index);
return;
}
int hours = Character.digit(text.charAt(index++), 10) * 10 + Character.digit(text.charAt(index++), 10);
if (size >= 3) {
if (text.charAt(index++) != ':') {
position.setErrorIndex(index);
return;
}
}
int minutes = 0;
if (size > 1) {
if (!Character.isDigit(text.charAt(index)) || !Character.isDigit(text.charAt(index + 1))) {
position.setErrorIndex(index);
return;
}
minutes = Character.digit(text.charAt(index++), 10) * 10 + Character.digit(text.charAt(index++), 10);
}
position.setIndex(index);
date.setTimeZone(getStaticTimeZone(sign * hours, minutes));
}
}
static boolean tryParseFixedTimeZone(String text, TCalendar date, TParsePosition position) { static boolean tryParseFixedTimeZone(String text, TCalendar date, TParsePosition position) {
general: if (position.getIndex() + 4 < text.length()) { general: if (position.getIndex() + 4 < text.length()) {
int signIndex = position.getIndex() + 3; int signIndex = position.getIndex() + 3;

View File

@ -161,6 +161,14 @@ class TSimpleDatePatternParser {
elements.add(new TDateFormatElement.Rfc822Timezone(locale)); elements.add(new TDateFormatElement.Rfc822Timezone(locale));
break; break;
} }
case 'X': {
int rep = parseRepetitions();
if (rep > 3) {
throw new IllegalArgumentException("Wrong number of repetitions of X pattern at " + index);
}
elements.add(new TDateFormatElement.Iso8601Timezone(rep));
break;
}
default: default:
if (isControl(c)) { if (isControl(c)) {
parseRepetitions(); parseRepetitions();