Created
March 17, 2012 20:11
-
-
Save andrewgilmartin/2064871 to your computer and use it in GitHub Desktop.
Parser for the common ISO 8061 date and timestamps.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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