null
, if unparsable.
*/
public static Date parse(String stamp) {
// initialize the compiled expressions once
if (c_pattern == null) {
c_pattern = new Pattern[c_expression.length];
for (int i = 0; i < c_expression.length; ++i) {
c_pattern[i] = Pattern.compile(c_expression[i]);
}
}
// match against pattern
for (int i = 0; i < c_expression.length; ++i) {
Matcher m = c_pattern[i].matcher(stamp);
if (m.matches()) {
Calendar c = Calendar.getInstance();
TimeZone z = TimeZone.getDefault();
if (m.group(9) != null && m.group(9).length() > 0) {
boolean utc = (Character.toUpperCase(m.group(9).charAt(0)) == 'Z');
if (utc) {
z = TimeZone.getTimeZone("GMT+0");
} else {
z = TimeZone.getTimeZone("GMT" + m.group(9));
}
}
c.setTimeZone(z);
c.set(Calendar.YEAR, Integer.parseInt(m.group(1)));
c.set(Calendar.MONTH,
Integer.parseInt(m.group(2)) + (Calendar.JANUARY - 1));
c.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(3)));
if (m.group(4).length() > 0) {
c.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(5)));
c.set(Calendar.MINUTE, Integer.parseInt(m.group(6)));
if (m.group(7) != null && m.group(7).length() > 0) {
c.set(Calendar.SECOND, Integer.parseInt(m.group(7)));
}
if (m.group(8) != null && m.group(8).length() > 1) {
String millis = m.group(8).substring(1);
while (millis.length() < 3) {
millis += "0";
}
millis = millis.substring(0, 3);
c.set(Calendar.MILLISECOND, Integer.parseInt(millis));
}
}
return c.getTime();
}
}
// not found
return null;
}
/**
* Ignores any internal date format, and tries to show a complete
* date/timp stamp of the current time in extended ISO 8601 format.
* UTC time (Zulu time) or a local timezone will be used. A sample for
* UTC output is 2002-04-23T02:49:58Z A sample for local zone
* (CDT) is 2002-04-22T21:49:58-05:00
*
* @param zuluTime returns a UTC formatted stamp, if true. Otherwise
* the time will be formatted according to the local zone.
* @return an ISO 8601 formatted date and time representation for the
* current time in extended format without millisecond resolution
* @see #iso8601( boolean, boolean, boolean, Date )
*/
public static String iso8601(boolean zuluTime) {
return Currently.iso8601(zuluTime, true, false, new Date());
}
/**
* Ignores any internal date format, and tries to show a complete
* date/timp stamp in extended ISO 8601 format. UTC time (Zulu time)
* or a local timezone will be used.* *
zone | format | fraction | example |
---|---|---|---|
local | basic | integral | 20020523T140427-0500 |
UTC | basic | integral | 20020523190427Z |
local | extd. | integral | 2002-05-23T14:04:27-05:00 |
UTC | extd. | integral | 2002-05-23T19:04:27Z |
local | basic | millis | 20020523T140427.166-0500 |
UTC | basic | millis | 20020523190427.166Z |
local | extd. | millis | 2002-05-23T14:04:27.166-05:00 |
UTC | extd. | millis | 2002-05-23T19:04:27.166Z |
* * @param zuluTime returns a UTC formatted stamp, if true. Otherwise * the time will be formatted according to the local zone. Local time * should be prefixed with the 'T'. * @param extendedFormat will use the extended ISO 8601 format which * separates the different timestamp items. If false, the basic * format will be used. In UTC and basic format, the 'T' separator * will be omitted. * @param withMillis will put the millisecond extension into the timestamp. * If false, the time will be without millisecond fraction. The separator * is taken from {@link java.text.DecimalFormatSymbols#getMinusSign()}, * which usually is a period or a comma. * @param now is a time stamp as Date. * @return an ISO 8601 formatted date and time representation for * the given point in time. */ public static String iso8601(boolean zuluTime, boolean extendedFormat, boolean withMillis, Date now) { Calendar c = Calendar.getInstance(zuluTime ? TimeZone.getTimeZone("UTC") : TimeZone.getDefault()); c.setTime(now); // set up formattting options DecimalFormat nf2 = new DecimalFormat("##00"); DecimalFormat nf3 = new DecimalFormat("###000"); DecimalFormat nf4 = new DecimalFormat("####0000"); DecimalFormatSymbols dfs = nf2.getDecimalFormatSymbols(); // allocate result string buffer int size = extendedFormat ? (zuluTime ? 25 : 30) : (zuluTime ? 21 : 25); if (!withMillis) { size -= 4; } StringBuffer result = new StringBuffer(size); result.append(nf4.format(c.get(Calendar.YEAR))); if (extendedFormat) { result.append('-'); // position 5 } result.append(nf2.format(c.get(Calendar.MONTH) + 1)); if (extendedFormat) { result.append('-'); // position 8 } result.append(nf2.format(c.get(Calendar.DAY_OF_MONTH))); // generating UTC in basic format may leave out the 'T' separator if (extendedFormat || !zuluTime) { result.append('T'); // position 11 } result.append(nf2.format(c.get(Calendar.HOUR_OF_DAY))); if (extendedFormat) { result.append(':'); // position 14 } result.append(nf2.format(c.get(Calendar.MINUTE))); if (extendedFormat) { result.append(':'); // position 17 } result.append(nf2.format(c.get(Calendar.SECOND))); if (withMillis) { // Though there is no explicit spec which allows a complete // timestamp with milliseconds, it is implied through two // levels, sigh. 5.3.4.2 allows decimal fractions with // time-only stamps that have a timezone. The intro of 5.4.2 // allows 5.3.1.3. result.append(dfs.getDecimalSeparator()); // position 20 result.append(nf3.format(c.get(Calendar.MILLISECOND))); } if (zuluTime) { // this is easy result.append('Z'); } else { // time zone calculations int zone_offset = c.get(Calendar.ZONE_OFFSET) / 1000; int save_offset = c.get(Calendar.DST_OFFSET) / 1000; int diff = (zone_offset + save_offset) / 60; result.append(diff < 0 ? dfs.getMinusSign() : '+'); // position 24 if (diff < 0) { diff = Math.abs(diff); } result.append(nf2.format(diff / 60)); if (extendedFormat) { result.append(':'); } result.append(nf2.format(diff % 60)); } return result.toString(); } }