/* See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * Esri Inc. 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 com.esri.gpt.framework.util; import java.io.Serializable; import java.sql.Date; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; /** * Serves as a proxy for the specification of a date. * <p> * The primary purpose is to support input date strings in standard * Java yyyy-MM-dd format. */ public class DateProxy implements Serializable { // class variables ============================================================= /** default time format used by class **/ public static String DEFAULT_TIME_FORMAT = "yyyy-MM-dd"; // instance variables ========================================================== private int _day = 0; private String _date = ""; private String _formattedInputDate = ""; private Timestamp _fromTimestamp = null; private Timestamp _fromTimestampExcl = null; private String _fullFormat = ""; private int _month = 0; private Timestamp _toTimestamp = null; private Timestamp _toTimestampExcl = null; private int _year = 0; // constructors ================================================================ /** Default constructor. */ public DateProxy() {} // properties ================================================================== /** * Sets the day. * @param day the day */ private void setDay(String day) { _day = Val.chkInt(day,0); } /** * Gets the input date string. * @return the input date string */ public String getDate() { return _date; } /** * Sets the input date string. * @param date the input date string */ public void setDate(String date) { _date = Val.chkStr(date); normalize(); if (getIsValid()) { _date = _formattedInputDate; } } /** * Determines if the date is valid. * @return true if the date is valid */ public boolean getIsValid() { return (_fromTimestamp != null); } /** * Sets the month. * @param month the month */ private void setMonth(String month) { _month = Val.chkInt(month,0); } /** * Determines if the input date string was invalid. * <p> * The input string is only considered invalid if it had non-zero * length and failed to eveluate to a date. * @return true if the input date string was invalid */ public boolean getWasInputStringInvalid() { return (!getIsValid() && (_date.length() > 0)); } /** * Sets the year. * @param year the year */ private void setYear(String year) { _year = Val.chkInt(year,0); } // methods ===================================================================== /** * Returns a timestamp applicable for the from part of a date range query. * @return the timestamp (null in unspecified) */ public Timestamp asFromTimestamp() { return _fromTimestamp; } /** * Returns an exclusive timestamp applicable for the from part of a date range query. * @return the timestamp (null in unspecified) */ public Timestamp asFromTimestampExcl() { return _fromTimestampExcl; } /** * Returns a timestamp applicable for the to part of a date range query. * @return the timestamp (null in unspecified) */ public Timestamp asToTimestamp() { return _toTimestamp; } /** * Returns an exclusive timestamp applicable for the to part of a date range query. * @return the timestamp (null in unspecified) */ public Timestamp asToTimestampExcl() { return _toTimestampExcl; } /** * Formats a date as "yyyy-MM-dd". * @param date the date to format * @return date represented as string */ public static String formatDate(Timestamp date) { SimpleDateFormat format = new SimpleDateFormat(DEFAULT_TIME_FORMAT); return format.format(date); } /** * Formats a timestamp as "yyyy-MM-dd'T'HH:mm:ssZ". * @param timestamp the timestamp to format * @return the formatted result */ public static String formatIso8601Timestamp(Timestamp timestamp) { String sTimestamp = ""; if (timestamp != null) { SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); sTimestamp = fmt.format(timestamp); sTimestamp = sTimestamp.substring(0,sTimestamp.length()-2) + ":" + sTimestamp.substring(sTimestamp.length()-2); } return sTimestamp; } /** * Normalizes the input date string into parts. */ private void normalize() { resetParts(); String sDate = Val.chkStr(_date).replaceAll("/","-"); if (sDate.endsWith("Z")) sDate = sDate.substring(0,sDate.length()-1); if (sDate.length() > 0) { // insert the "-" delimiter if (sDate.indexOf("-") == -1) { if (sDate.length() == 8) { sDate = sDate.substring(0,4)+"-"+sDate.substring(4,6)+ "-"+sDate.substring(6,8); } else if (sDate.length() == 6) { sDate = sDate.substring(0,4)+"-"+sDate.substring(4,6); } else if (sDate.length() == 4) { sDate = sDate.substring(0,4); } } // tokenize the parts String[] aDate = Val.tokenize(sDate,"-"); if (aDate.length == 3) { setYear(aDate[0]); setMonth(aDate[1]); setDay(aDate[2]); } else if (aDate.length == 2) { setYear(aDate[0]); setMonth(aDate[1]); } else if (aDate.length == 1) { setYear(aDate[0]); } // make the yyyy-MM-dd string String yyyyMMdd = ""; if (_year > 0) { String sYear = ""+_year; if (sYear.length() == 1) { sYear = "200"+sYear; } else if (sYear.length() == 2) { sYear = "20"+sYear; } while (sYear.length() < 4) sYear = "0"+sYear; yyyyMMdd = sYear; if (_month > 0) { String sMonth = ""+_month; while (sMonth.length() < 2) sMonth = "0"+sMonth; yyyyMMdd += "-"+sMonth; if (_day > 0) { String sDay = ""+_day; while (sDay.length() < 2) sDay = "0"+sDay; yyyyMMdd += "-"+sDay; } else { yyyyMMdd += "-01"; } } else { yyyyMMdd += "-01-01"; } } // set the timestamps and formated date strings if (yyyyMMdd.length() > 0) { try { // set the from and to timestamps _fromTimestamp = new Timestamp(Date.valueOf(yyyyMMdd).getTime()); GregorianCalendar calendar = new GregorianCalendar(); calendar.setTimeInMillis(_fromTimestamp.getTime()); if (_month <= 0) { calendar.add(Calendar.YEAR,1); } else if (_day <= 0) { calendar.add(Calendar.MONTH,1); } else { calendar.add(Calendar.DAY_OF_MONTH,1); } _fromTimestampExcl = new Timestamp(calendar.getTimeInMillis()); calendar.add(Calendar.SECOND,-1); _toTimestamp = new Timestamp(calendar.getTimeInMillis()); if (_month <= 0) { calendar.add(Calendar.YEAR,-1); } else if (_day <= 0) { calendar.add(Calendar.MONTH,-1); } else { calendar.add(Calendar.DAY_OF_MONTH,-1); } _toTimestampExcl = new Timestamp(calendar.getTimeInMillis()); // set the full format, // set the formatted input data (according to the parts supplied) _fullFormat = DateProxy.formatDate(_fromTimestamp); _formattedInputDate = _fullFormat; if (_month <= 0) { _formattedInputDate = _formattedInputDate.substring(0,4); } else if (_day <= 0) { _formattedInputDate = _formattedInputDate.substring(0,7); } } catch (Exception e) { resetParts(); } } } } /** * Resets the date parts. */ private void resetParts() { _day = 0; _month = 0; _year = 0; _fromTimestamp = null; _toTimestamp = null; _fullFormat = ""; _formattedInputDate = ""; } /** * Subtract number of days from current date * @param daysToSubtract number of days to Subtract * @return the Subtracted timestamp */ public static Timestamp subtractDays(int daysToSubtract) { GregorianCalendar cal = new GregorianCalendar(); cal.setTimeInMillis(System.currentTimeMillis()); cal.add(Calendar.DAY_OF_MONTH, (-1 * daysToSubtract)); return new Timestamp(cal.getTimeInMillis()); } /** * Returns a string representation this object. * @return the string */ @Override public String toString() { StringBuffer sb = new StringBuffer(getClass().getName()).append(" (\n"); sb.append(" date=").append(_date).append("\n"); sb.append(" isValid=").append(getIsValid()).append("\n"); sb.append(" formattedInputDate=").append(_formattedInputDate).append("\n"); sb.append(" fullFormat=").append(_fullFormat).append("\n"); sb.append(" year=").append(_year); sb.append(" month=").append(_month); sb.append(" day=").append(_day).append("\n"); sb.append(" fromTimestamp=").append(_fromTimestamp).append("\n"); sb.append(" toTimestamp=").append(_toTimestamp).append("\n"); sb.append(") ===== end ").append(getClass().getName()); return sb.toString(); } }