Java tutorial
/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.elasticsearch.hadoop.util; import java.lang.reflect.Method; import java.util.Calendar; import javax.xml.bind.DatatypeConverter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Utility used for parsing date ISO8601. * Morphed into a runtime bridge over possible ISO8601 (simply because the spec is too large, especially when considering the various optional formats). */ public abstract class DateUtils { public static boolean printed = false; private final static boolean jodaTimeAvailable = ObjectUtils .isClassPresent("org.joda.time.format.ISODateTimeFormat", DateUtils.class.getClassLoader()); private static abstract class Jdk6 { // Parses ISO date through the JDK XML bind class. However the spec doesn't support all ISO8601 formats which this class tries to address // in particular Time offsets from UTC are available in 3 forms: // The offset from UTC is appended to the time in the same way that 'Z' was above, in the form [hh]:[mm], [hh][mm], or [hh]. // // XML Bind supports only the first one. public static Calendar parseDate(String value) { // check for colon in the time offset int timeZoneIndex = value.indexOf("T"); if (timeZoneIndex > 0) { int sign = value.indexOf("+", timeZoneIndex); if (sign < 0) { sign = value.indexOf("-", timeZoneIndex); } // +4 means it's either hh:mm or hhmm if (sign > 0) { // +3 points to either : or m int colonIndex = sign + 3; // +hh - need to add :mm if (colonIndex >= value.length()) { value = value + ":00"; } else if (value.charAt(colonIndex) != ':') { value = value.substring(0, colonIndex) + ":" + value.substring(colonIndex); } } } return DatatypeConverter.parseDateTime(value); } } private static abstract class JodaTime { private static final Object DATE_OPTIONAL_TIME_FORMATTER; private static final Method PARSE_DATE_TIME; private static final Method TO_CALENDAR; private static final boolean INITIALIZED; static { boolean init = false; Method parseDateTime = null, toCalendar = null; Object dotf = null; try { ClassLoader cl = JodaTime.class.getClassLoader(); Class<?> FORMAT_CLASS = ObjectUtils.loadClass("org.joda.time.format.ISODateTimeFormat", cl); Method DATE_OPTIONAL_TIME = ReflectionUtils.findMethod(FORMAT_CLASS, "dateOptionalTimeParser"); dotf = ReflectionUtils.invoke(DATE_OPTIONAL_TIME, null); parseDateTime = ReflectionUtils.findMethod(dotf.getClass(), "parseDateTime", String.class); Class<?> DATE_TIME_CLASS = ObjectUtils.loadClass("org.joda.time.DateTime", cl); toCalendar = ReflectionUtils.findMethod(DATE_TIME_CLASS, "toGregorianCalendar"); init = true; } catch (Exception ex) { // log exception } DATE_OPTIONAL_TIME_FORMATTER = dotf; PARSE_DATE_TIME = parseDateTime; TO_CALENDAR = toCalendar; INITIALIZED = init; } public static Calendar parseDate(String value) { Object dt = ReflectionUtils.invoke(PARSE_DATE_TIME, DATE_OPTIONAL_TIME_FORMATTER, value); return ReflectionUtils.invoke(TO_CALENDAR, dt); } } public static Calendar parseDate(String value) { if (!printed) { printed = true; Log log = LogFactory.getLog(DateUtils.class); if (jodaTimeAvailable && JodaTime.INITIALIZED) { log.info("Joda library available in the classpath; using it for date/time handling..."); } else { // be silent otherwise } } return (jodaTimeAvailable && JodaTime.INITIALIZED) ? JodaTime.parseDate(value) : Jdk6.parseDate(value); } }