Java tutorial
//package com.java2s; import java.util.*; public class Main { /** * ID to represent the 'GMT' string */ private static final String GMT_ID = "GMT"; /** * Parse a date from ISO-8601 formatted string. It expects a format yyyy-MM-ddThh:mm:ss[.sss][Z|[+-]hh:mm] * * @param date ISO string to parse in the appropriate format. * @return the parsed date * @throws IllegalArgumentException if the date is not in the appropriate format */ public static Date parse(String date) { try { int offset = 0; // extract year int year = parseInt(date, offset, offset += 4); checkOffset(date, offset, '-'); // extract month int month = parseInt(date, offset += 1, offset += 2); checkOffset(date, offset, '-'); // extract day int day = parseInt(date, offset += 1, offset += 2); checkOffset(date, offset, 'T'); // extract hours, minutes, seconds and milliseconds int hour = parseInt(date, offset += 1, offset += 2); checkOffset(date, offset, ':'); int minutes = parseInt(date, offset += 1, offset += 2); checkOffset(date, offset, ':'); int seconds = parseInt(date, offset += 1, offset += 2); // milliseconds can be optional in the format int milliseconds = 0; // always use 0 otherwise returned date will include millis of current time if (date.charAt(offset) == '.') { checkOffset(date, offset, '.'); milliseconds = parseInt(date, offset += 1, offset += 3); } // extract timezone String timezoneId; char timezoneIndicator = date.charAt(offset); if (timezoneIndicator == '+' || timezoneIndicator == '-') { timezoneId = GMT_ID + date.substring(offset); } else if (timezoneIndicator == 'Z') { timezoneId = GMT_ID; } else { throw new IndexOutOfBoundsException("Invalid time zone indicator " + timezoneIndicator); } TimeZone timezone = TimeZone.getTimeZone(timezoneId); if (!timezone.getID().equals(timezoneId)) { throw new IndexOutOfBoundsException(); } Calendar calendar = new GregorianCalendar(timezone); calendar.setLenient(false); calendar.set(Calendar.YEAR, year); calendar.set(Calendar.MONTH, month - 1); calendar.set(Calendar.DAY_OF_MONTH, day); calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minutes); calendar.set(Calendar.SECOND, seconds); calendar.set(Calendar.MILLISECOND, milliseconds); return calendar.getTime(); } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException("Failed to parse date " + date, e); } catch (NumberFormatException e) { throw new IllegalArgumentException("Failed to parse date " + date, e); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Failed to parse date " + date, e); } } /** * Parse an integer located between 2 given offsets in a string * * @param value the string to parse * @param beginIndex the start index for the integer in the string * @param endIndex the end index for the integer in the string * @return the int * @throws NumberFormatException if the value is not a number */ private static int parseInt(String value, int beginIndex, int endIndex) throws NumberFormatException { if (beginIndex < 0 || endIndex > value.length() || beginIndex > endIndex) { throw new NumberFormatException(value); } // use same logic as in Integer.parseInt() but less generic we're not supporting negative values int i = beginIndex; int result = 0; int digit; if (i < endIndex) { digit = Character.digit(value.charAt(i++), 10); if (digit < 0) { throw new NumberFormatException("Invalid number: " + value); } result = -digit; } while (i < endIndex) { digit = Character.digit(value.charAt(i++), 10); if (digit < 0) { throw new NumberFormatException("Invalid number: " + value); } result *= 10; result -= digit; } return -result; } /** * Check if the expected character exist at the given offset of the * * @param value the string to check at the specified offset * @param offset the offset to look for the expected character * @param expected the expected character * @throws IndexOutOfBoundsException if the expected character is not found */ private static void checkOffset(String value, int offset, char expected) throws IndexOutOfBoundsException { char found = value.charAt(offset); if (found != expected) { throw new IndexOutOfBoundsException("Expected '" + expected + "' character but found '" + found + "'"); } } }