at.spardat.enterprise.fmt.ADateFmt Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat GmbH .
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
// @(#) $Id: ADateFmt.java 2093 2007-11-28 14:23:36Z s3460 $
package at.spardat.enterprise.fmt;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import at.spardat.enterprise.exc.SysException;
import at.spardat.enterprise.util.DateUtil;
import at.spardat.enterprise.util.Types;
/**
* This class supports formatting and parsig ADates. What makes this class different from
* java.text.DateFormat is the better implementation of the MEDIUM style. To put
* it briefly, you should only use the MEDIUM style for parsing of dates. Moreover, the
* formatting of dates with format MEDIUM has been highly optimized.
*
* For styles other than MEDIUM, the implementation falls back to java.text.DateFormat.
*/
public abstract class ADateFmt extends IFmt {
/**
* denotes a predefined format, see java.text.DateFormat.SHORT. In most locales,
* the year is just of two digits, therefore not adequate for input.
* Example: '24.04.00'
*/
public static final int SHORT = IFmt.LAST_STYLE*2;
/**
* This is the default style. It is the preferred style for entering dates, since there is much
* input support, also see {@link ADateFmtMediumSmart}. Example: '24.04.2000'
*/
public static final int MEDIUM = SHORT*2;
/**
* A longer representation of a date, see java.text.DateFormat.LONG.
* Example: '24. April 2000'
*/
public static final int LONG = MEDIUM*2;
/**
* A very verbose representation, see java.text.DateFormat.FULL.
* Example: 'Montag, 24. April 2000'
*/
public static final int FULL = LONG*2;
/**
* Allows to define a lower bound for a date that is specified relatively to the current
* date. -1 is yesterday, 0 is today and 1 denotes tomorrow. Integer.MAX_VALUE
* means that there is no lower bound.
*/
private int min_ = Integer.MAX_VALUE;
/**
* Allows to define a upper bound for a date that is specified relatively to the current
* date. -1 is yesterday, 0 is today and 1 denotes tomorrow. Integer.MAX_VALUE
* means that there is no upper bound.
*/
private int max_ = Integer.MAX_VALUE;
/**
* Allows to define a lower bound for a date that is specified absolutly.
*/
private Date minDate_;
/**
* Allows to define an upper bound for a date that is specified absolutly.
*/
private Date maxDate_;
/**
* Returns an IFmt providing a style and a locale. For style DEFAULT
* or MEDIUM, an efficient implementation with convenient input support
* is returned, for other styles, the default implementation of JDK
* is used.
*
* @param style one of SHORT, MEDIUM, LONG or FULL or one of the IFmt-styles.
* @param locale the locale to use
*/
public static ADateFmt getInstance (int style, Locale locale) {
ADateFmt toReturn = null;
if ((style & SHORT) != 0 || (style & LONG) != 0 || (style & FULL) != 0) {
toReturn = new ADateFmtJavaUtilText (style, locale);
} else {
toReturn = ADateFmtMediumSmart.getInstance (locale, style);
}
return toReturn;
}
/**
* Returns an IFmt providing a style and a locale. For style DEFAULT
* or MEDIUM, an efficient implementation with convenient input support
* is returned, for other styles, the default implementation of JDK
* is used.
*
* @param style one of SHORT, MEDIUM, LONG or FULL or one of the IFmt-styles.
* @param locale the locale to use
* @param minDayRel lower bound on acceptable dates expressed as day-offset
* relative to today, i.e., -1 is yesterday, 0 is today, 1 stands
* for tomorrow. Integer.MAX_VALUE stands for no restriction.
* @param maxDayRel upper bound on acceptable dates expressed as day-offset
* relative to today, i.e., -1 is yesterday, 0 is today, 1 stands
* for tomorrow. Integer.MAX_VALUE stands for no restriction.
*/
public static ADateFmt getInstance (int style, Locale locale, int minDayRel, int maxDayRel) {
ADateFmt fmt = getInstance (style, locale);
fmt.setMin(minDayRel);
fmt.setMax(maxDayRel);
return fmt;
}
/**
* Returns an IFmt providing a style and a locale. For style DEFAULT
* or MEDIUM, an efficient implementation with convenient input support
* is returned, for other styles, the default implementation of JDK
* is used.
*
* @param style one of SHORT, MEDIUM, LONG or FULL or one of the IFmt-styles.
* @param locale the locale to use
* @param minDate lower bound on acceptable dates in the format yyyyMMdd
.
* null and "" stand for no restriction.
* @param maxDate upper bound on acceptable dates in the format yyyyMMdd
.
* null and "" stand for no restriction.
*/
public static ADateFmt getInstance (int style, Locale locale, String minDate, String maxDate) {
ADateFmt fmt = getInstance (style, locale);
fmt.setMinDate(minDate);
fmt.setMaxDate(maxDate);
return fmt;
}
/**
* Returns an IFmt providing a style and a locale. For style DEFAULT
* or MEDIUM, an efficient implementation with convenient input support
* is returned, for other styles, the default implementation of JDK
* is used.
*
* @param style one of SHORT, MEDIUM, LONG or FULL or one of the IFmt-styles.
* @param locale the locale to use
* @param minDayRel lower bound on acceptable dates expressed as day-offset
* relative to today, i.e., -1 is yesterday, 0 is today, 1 stands
* for tomorrow. Integer.MAX_VALUE stands for no restriction.
* @param maxDayRel upper bound on acceptable dates expressed as day-offset
* relative to today, i.e., -1 is yesterday, 0 is today, 1 stands
* for tomorrow. Integer.MAX_VALUE stands for no restriction.
* @param minDate lower bound on acceptable dates in the format yyyyMMdd
.
* null and "" stand for no restriction.
* @param maxDate upper bound on acceptable dates in the format yyyyMMdd
.
* null and "" stand for no restriction.
*/
public static ADateFmt getInstance (int style, Locale locale, int minDayRel, int maxDayRel, String minDate, String maxDate) {
ADateFmt fmt = getInstance (style, locale);
fmt.setMin(minDayRel);
fmt.setMax(maxDayRel);
fmt.setMinDate(minDate);
fmt.setMaxDate(maxDate);
return fmt;
}
/**
* Constructs an ADateFmt providing a pattern as specified in
* java.text.SimpleDateFormat.
*/
public static ADateFmt getInstance (String pattern) {
return new ADateFmtJavaUtilText (pattern, 0);
}
/**
* Constructs an ADateFmt providing a pattern as specified in
* java.text.SimpleDateFormat.
*
* @param pattern a SimpleDateFormat pattern.
* @param style may be MANDATORY
*/
public static ADateFmt getInstance (String pattern, int style) {
return new ADateFmtJavaUtilText (pattern, style);
}
/**
* Constructs an ADateFmt providing a pattern as specified in
* java.text.SimpleDateFormat.
*
* @param pattern a SimpleDateFormat pattern.
* @param style may be MANDATORY
* @param locale as used in java.text.SimpleDateFormat
*/
public static ADateFmt getInstance (String pattern, int style, Locale locale) {
return new ADateFmtJavaUtilText (pattern, style, locale);
}
/**
* @see at.spardat.enterprise.fmt.IFmt#isLegalInternal(String)
*/
public boolean isLegalInternal (String internal) {
if (internal == null || internal.length() == 0) return true; // empty representation
return DateUtil.isValid (internal);
}
/**
* @see at.spardat.enterprise.fmt.IFmt#mayBeAppliedTo(byte)
*/
public boolean mayBeAppliedTo (byte type) {
return type == Types.T_DATE;
}
/**
* Returns the upper bound for a date that is specified relatively to the current
* date. -1 is yesterday, 0 is today and 1 denotes tomorrow. Integer.MAX_VALUE
* means that there is no upper bound.
*/
public int getMax () {
return max_;
}
/**
* Returns the lower bound for a date that is specified relatively to the current
* date. -1 is yesterday, 0 is today and 1 denotes tomorrow. Integer.MAX_VALUE
* means that there is no lower bound.
*/
public int getMin () {
return min_;
}
/**
* Allows to set the upper bound for a date that is specified relatively to the current
* date. -1 is yesterday, 0 is today and 1 denotes tomorrow. Integer.MAX_VALUE
* means that there is no upper bound.
*/
public void setMax (int i) {
max_ = i;
}
/**
* Allows to set the lower bound for a date that is specified relatively to the current
* date. -1 is yesterday, 0 is today and 1 denotes tomorrow. Integer.MAX_VALUE
* means that there is no lower bound.
*/
public void setMin (int i) {
min_ = i;
}
/**
* Returns the upper bound for a date in the format yyyyMMdd
,
* or null if no such restriction is set.
*/
public String getMaxDate() {
if(maxDate_==null) return null;
else return new SimpleDateFormat("yyyyMMdd").format(maxDate_);
}
/**
* Set the upper bound for a date in the format yyyyMMdd
.
* null and "" mean no restriction.
*/
public void setMaxDate(String maxDate) {
try {
if(maxDate==null||maxDate.length()==0) maxDate_=null;
else maxDate_ = new SimpleDateFormat("yyyyMMdd").parse(maxDate);
} catch (ParseException e) {
throw new SysException(e);
}
}
/**
* Returns the lower bound for a date in the format yyyyMMdd
,
* or null if no such restriction is set.
*/
public String getMinDate() {
if(minDate_==null) return null;
else return new SimpleDateFormat("yyyyMMdd").format(minDate_);
}
/**
* Set the lower bound for a date in the format yyyyMMdd
.
* null and "" mean no restriction.
*/
public void setMinDate(String minDate) {
try {
if(minDate==null||minDate.length()==0) minDate_=null;
else minDate_ = new SimpleDateFormat("yyyyMMdd").parse(minDate);
} catch (ParseException e) {
throw new SysException(e);
}
}
/**
* Utility-method that checks the date-ranges, if any. Must be called from
* subclasses in their parse-method.
*
* @param internal internal date String.
*/
protected void checkDateRange (String internal) {
if (internal == null || internal.length() == 0) return;
if (min_ == Integer.MAX_VALUE && max_ == Integer.MAX_VALUE && minDate_ == null && maxDate_ == null) return;
GregorianCalendar today = new GregorianCalendar ();
// gub bugfix: check the entered date
try {
today.setTime(new SimpleDateFormat("yyyyMMdd").parse(internal));
} catch (ParseException e) {
throw new SysException("internal date string format error: "+internal);
}
// end bugfix
DateUtil.resetTime (today);
if (min_ != Integer.MAX_VALUE) {
GregorianCalendar min = new GregorianCalendar ();
DateUtil.resetTime (min);
min.add(Calendar.DATE, min_);
if (min.after (today)) {
throw new FmtParseException ("ADateMin", gCalAsString (min));
}
}
if (max_ != Integer.MAX_VALUE) {
GregorianCalendar max = new GregorianCalendar ();
DateUtil.resetTime (max);
max.add(Calendar.DATE, max_);
if (max.before (today)) {
throw new FmtParseException ("ADateMax", gCalAsString (max));
}
}
if(minDate_!=null) {
GregorianCalendar min = new GregorianCalendar ();
min.setTime(minDate_);
DateUtil.resetTime(min);
if (min.after (today)) {
throw new FmtParseException ("ADateMin", gCalAsString (min));
}
}
if(maxDate_!=null) {
GregorianCalendar max = new GregorianCalendar ();
max.setTime(maxDate_);
DateUtil.resetTime(max);
if (max.before (today)) {
throw new FmtParseException ("ADateMax", gCalAsString (max));
}
}
}
/**
* Returns a formatted string where the value is taken from a
* provided CregorianCalendar.
*/
private String gCalAsString (GregorianCalendar cal) {
SimpleDateFormat df = new SimpleDateFormat ("yyyyMMdd");
return format (df.format(cal.getTime()));
}
}