/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2006-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.filter.text.commons; import java.util.Calendar; import java.util.Date; /** * Duration utility class * <p> * Maintains convenient methods to manipulate the duration information. * </p> * * @since 2.5 * * @author Mauricio Pazos - Axios Engineering * @author Gabriel Roldan - Axios Engineering * @version $Id$ * @source $URL: * http://svn.geotools.org/geotools/trunk/gt/modules/library/cql/src/main/java/org/geotools/text/filter/cql2/DurationUtil.java $ */ final class DurationUtil { private static final Calendar CALENDAR = Calendar.getInstance(); private static final int YEARS = 0; private static final int MONTHS = 1; private static final int DAYS = 2; private static final int HOURS = 0; private static final int MINUTES = 1; private static final int SECONDS = 2; /** H,M,S */ private static int[] DURATION_TIME = new int[3]; private DurationUtil() { // utility class } /** * Extract from duration string the values of years, month and days * * @param duration * @return int[3] with years,months,days, if some value are not present -1 * will be returned. */ private static int[] extractDurationDate(final String duration) { // initializes duration date container /** Y,M,D */ int[] durationDate = new int[3]; for (int i = 0; i < durationDate.length; i++) { durationDate[i] = -1; } // if has not duration date return array with -1 values int cursor = duration.indexOf("P"); if (cursor == -1) { return durationDate; } // extracts duration date and set duration array cursor++; // years int endYears = duration.indexOf("Y", cursor); if (endYears >= 0) { String strYears = duration.substring(cursor, endYears); int years = Integer.parseInt(strYears); durationDate[YEARS] = years; cursor = endYears + 1; } // months int endMonths = duration.indexOf("M", cursor); if (endMonths >= 0) { String strMonths = duration.substring(cursor, endMonths); int months = Integer.parseInt(strMonths); durationDate[MONTHS] = months; cursor = endMonths + 1; } // days int endDays = duration.indexOf("D", cursor); if (endDays >= 0) { String strDays = duration.substring(cursor, endDays); int days = Integer.parseInt(strDays); durationDate[DAYS] = days; } return durationDate; } /** * Extract from duration string the values of hours, minutes and seconds * * @param duration * @return int[3] with hours, minutes and seconds if some value are not * present -1 will be returned. */ private static int[] extractDurationTime(final String duration) { for (int i = 0; i < DURATION_TIME.length; i++) { DURATION_TIME[i] = -1; } int cursor = duration.indexOf("T"); if (cursor == -1) { return DURATION_TIME; } cursor++; // hours int endHours = duration.indexOf("H", cursor); if (endHours >= 0) { String strHours = duration.substring(cursor, endHours); int hours = Integer.parseInt(strHours); DURATION_TIME[HOURS] = hours; cursor = endHours + 1; } // minute int endMinutes = duration.indexOf("M", cursor); if (endMinutes >= 0) { String strMinutes = duration.substring(cursor, endMinutes); int minutes = Integer.parseInt(strMinutes); DURATION_TIME[MINUTES] = minutes; cursor = endMinutes + 1; } // seconds int endSeconds = duration.indexOf("S", cursor); if (endSeconds >= 0) { String strSeconds = duration.substring(cursor, endSeconds); int seconds = Integer.parseInt(strSeconds); DURATION_TIME[SECONDS] = seconds; } return DURATION_TIME; } /** * Add duration to date * * @param date * a Date * @param duration * a String formated like "P##Y##M##D" * * @return a Date * */ public static Date addDurationToDate(final Date date, final String duration) throws NumberFormatException { final int positive = 1; Date computedDate = null; computedDate = computeDateFromDurationDate(date, duration, positive); computedDate = computeDateFromDurationTime(computedDate, duration, positive); return computedDate; } /** * Adds years, month and days (duration) to initial date. * * @param date * initial date * @param duration * a String with format: PddYddMddD * @return Date a computed date. if duration have not got duration "P" * return date value. * */ private static Date computeDateFromDurationDate(final Date date, final String duration, int sign) { int[] durationDate = new int[3]; durationDate = extractDurationDate(duration); if (isNull(durationDate)) { return date; } CALENDAR.setTime(date); // years if (durationDate[YEARS] >= 0) { CALENDAR.add(Calendar.YEAR, sign * durationDate[YEARS]); } // months if (durationDate[MONTHS] >= 0) { CALENDAR.add(Calendar.MONTH, sign * durationDate[MONTHS]); } // days if (durationDate[DAYS] >= 0) { CALENDAR.add(Calendar.DATE, sign * durationDate[DAYS]); } Date lastDate = CALENDAR.getTime(); return lastDate; } /** * durDate is null if all his values are -1 * * @param durDate * @return true if has some greater than or equal 0 */ private static boolean isNull(int[] durDate) { for (int i = 0; i < durDate.length; i++) { if (durDate[i] >= 0) { return false; } } return true; } /** * Add or subtract time duration to initial date. * * @param date * initial date * @param duration * a String with format: TddHddMddS * @param sign * 1 or -1 (add or subract) * @return Date a computed date. if duration have not got duration "T" * return date value. */ private static Date computeDateFromDurationTime(final Date date, final String duration, final int sign) { DURATION_TIME = extractDurationTime(duration); if (isNull(DURATION_TIME)) { return date; } CALENDAR.setTime(date); // hours if (DURATION_TIME[HOURS] >= 0) { CALENDAR.add(Calendar.HOUR, sign * DURATION_TIME[HOURS]); } // minute if (DURATION_TIME[MINUTES] >= 0) { CALENDAR.add(Calendar.MINUTE, sign * DURATION_TIME[MINUTES]); } // seconds if (DURATION_TIME[SECONDS] >= 0) { CALENDAR.add(Calendar.SECOND, sign * DURATION_TIME[SECONDS]); } Date lastDate = CALENDAR.getTime(); return lastDate; } /** * Subtracts duration to date * * @param date * a Date * @param duration * a String formated like "P##Y##M##D" * * @return a Date */ public static Date subtractDurationToDate(Date date, String duration) { final int negative = -1; Date computedDate = null; computedDate = computeDateFromDurationDate(date, duration, negative); computedDate = computeDateFromDurationTime(computedDate, duration, negative); return computedDate; } }