Skip to content

Instantly share code, notes, and snippets.

@andrewgilmartin
Created March 17, 2012 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewgilmartin/2064871 to your computer and use it in GitHub Desktop.
Save andrewgilmartin/2064871 to your computer and use it in GitHub Desktop.
Parser for the common ISO 8061 date and timestamps.
/**
* Returns the timestamp parsed from the given ISO 8061 UTC string. Note
* that all of the following timestamp forms are supported: {@code
*
* YYYY := YYYY-01-01T00:00:00.0Z
* YYYY-MM := YYYY-MM-01T00:00:00.0Z
* YYYY-MM-DD := YYYY-MM-DDT00:00:00.0Z
* YYYY-MM-DD'T'HH := YYYY-MM-DDTHH:00:00.0Z
* YYYY-MM-DD'T'HH:MM := YYYY-MM-DDTHH:MM:00.0Z
* YYYY-MM-DD'T'HH:MM:SS := YYYY-MM-DDTHH:MM:SS.0Z
* YYYY-MM-DD'T'HH:MM:SS'Z' := YYYY-MM-DDTHH:MM:SS.0Z
* YYYY-MM-DD'T'HH:MM:SS.S := YYYY-MM-DDTHH:MM:SS.SZ
* YYYY-MM-DD'T'HH:MM:SS.S'Z' := YYYY-MM-DDTHH:MM:SS.SZ
* }
*
* @param text is the external date or timestamp representation. Value must
* not be null.
*/
public static Timestamp parseValue(String text) throws ParseException {
int year = 0;
int month = 0;
int day = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
int fractionalSeconds = 0;
int state = 0;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
switch (state) {
case 0:
// year
if (c == '-') {
state = 1;
}
else if ('0' <= c && c <= '9') {
year = year * 10 + (c - '0');
}
else {
throw new ParseException(text, i);
}
continue;
case 1:
// month
if (c == '-') {
state = 2;
}
else if ('0' <= c && c <= '9') {
month = month * 10 + (c - '0');
}
else {
throw new ParseException(text, i);
}
continue;
case 2:
// day
if (c == 'T') {
state = 3;
}
else if ('0' <= c && c <= '9') {
day = day * 10 + (c - '0');
}
else {
throw new ParseException(text, i);
}
continue;
case 3:
// hours
if (c == ':') {
state = 4;
}
else if ('0' <= c && c <= '9') {
hours = hours * 10 + (c - '0');
}
else {
throw new ParseException(text, i);
}
continue;
case 4:
// minutes
if (c == ':') {
state = 5;
}
else if ('0' <= c && c <= '9') {
minutes = minutes * 10 + (c - '0');
}
else {
throw new ParseException(text, i);
}
continue;
case 5:
// seconds
if (c == '.') {
state = 6;
}
else if (c == 'Z') {
state = 7;
}
else if ('0' <= c && c <= '9') {
seconds = seconds * 10 + (c - '0');
}
else {
throw new ParseException(text, i);
}
continue;
case 6:
// fractional seconds
if (c == 'Z') {
state = 7;
}
else if ('0' <= c && c <= '9') {
fractionalSeconds = fractionalSeconds * 10 + (c - '0');
}
else {
throw new ParseException(text, i);
}
continue;
case 7:
throw new ParseException(text, i);
}
}
// Note: Not using Calendar as it does not support fractional seconds.
return new Timestamp(
(year - 1900),
(month == 0 ? 1 : (month - 1)),
(day == 0 ? 1 : day),
hours,
minutes,
seconds,
fractionalSeconds);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment