package mil.nga.giat.geowave.core.geotime; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class contains a set of Temporal utility methods that are generally * useful throughout the GeoWave core codebase. */ public class TimeUtils { private final static Logger LOGGER = LoggerFactory.getLogger(TimeUtils.class); /** * Convert a calendar object to a long in the form of milliseconds since the * epoch of January 1, 1970. The time is converted to GMT if it is not * already in that timezone so that all times will be in a standard * timezone. * * @param cal * The calendar object * @return The time in milliseconds */ public static long calendarToGMTMillis( Calendar cal ) { // get Date object representing this Calendar's time value, millisecond // offset from the Epoch, January 1, 1970 00:00:00.000 GMT (Gregorian) Date date = cal.getTime(); // Returns the number of milliseconds since January 1, 1970, 00:00:00 // GMT represented by this Date object. long time = date.getTime(); return time; } /** * Get the time in millis of this temporal object (either numeric * interpreted as millisecond time in GMT, Date, or Calendar) * * @param timeObj * The temporal object * @return The time in milliseconds since the epoch in GMT */ public static long getTimeMillis( Object timeObj ) { // handle dates, calendars, and Numbers only if (timeObj != null) { if (timeObj instanceof Calendar) { return calendarToGMTMillis(((Calendar) timeObj)); } else if (timeObj instanceof Date) { return ((Date) timeObj).getTime(); } else if (timeObj instanceof Number) { return ((Number) timeObj).longValue(); } else { LOGGER.warn("Time value '" + timeObj + "' of type '" + timeObj.getClass() + "' is not of expected temporal type"); } } return -1; } /** * Determine if this class is a supported temporal class. Numeric classes * are not determined to be temporal in this case even though they can be * interpreted as milliseconds because we do not want to be over-selective * and mis-interpret numeric fields * * @param bindingClass * The binding class of the attribute * @return A flag indicating whether the class is temporal */ public static boolean isTemporal( Class<?> bindingClass ) { // because Longs can also be numeric, just allow Dates and Calendars // class bindings to be temporal return (Calendar.class.isAssignableFrom(bindingClass) || Date.class.isAssignableFrom(bindingClass)); } /** * Instantiates the class type as a new object with the temporal value being * the longVal interpreted as milliseconds since the epoch in GMT * * @param bindingClass * The class to try to instantiate for this time value. Currently * java.util.Calendar, java.util.Date, and java.lang.Long are * supported. * @param longVal * A value to be interpreted as milliseconds since the epoch in * GMT * @return An instance of the binding class with the value interpreted from * longVal */ public static Object getTimeValue( Class<?> bindingClass, long longVal ) { if (longVal < 0) { // indicator that the time value is null; return null; } if (Calendar.class.isAssignableFrom(bindingClass)) { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); cal.setTimeInMillis(longVal); return cal; } else if (Date.class.isAssignableFrom(bindingClass)) { return new Date( longVal); } else if (Long.class.isAssignableFrom(bindingClass)) { return Long.valueOf(longVal); } LOGGER.warn("Numeric value '" + longVal + "' of type '" + bindingClass + "' is not of expected temporal type"); return null; } }