View Javadoc

    1   /*
    2    * $Id: CalendarValidator.java 386637 2006-03-17 13:22:26Z niallp $
    3    * $Revision: 386637 $
    4    * $Date: 2006-03-17 13:22:26 +0000 (Fri, 17 Mar 2006) $
    5    *
    6    * ====================================================================
    7    * Copyright 2006 The Apache Software Foundation
    8    *
    9    * Licensed under the Apache License, Version 2.0 (the "License");
    10   * you may not use this file except in compliance with the License.
    11   * You may obtain a copy of the License at
    12   *
    13   *     http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing, software
    16   * distributed under the License is distributed on an "AS IS" BASIS,
    17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18   * See the License for the specific language governing permissions and
    19   * limitations under the License.
    20   */
    21  package org.apache.commons.validator.routines;
    22
    23  import java.text.DateFormat;
    24  import java.text.Format;
    25  import java.util.Calendar;
    26  import java.util.Locale;
    27  import java.util.TimeZone;
    28
    29  /***
    30   * <p><b>Calendar Validation</b> and Conversion routines (<code>java.util.Calendar</code>).</p>
    31   *
    32   * <p>This validator provides a number of methods for validating/converting
    33   *    a <code>String</code> date value to a <code>java.util.Calendar</code> using
    34   *    <code>java.text.DateFormat</code> to parse either:</p>
    35   *    <ul>
    36   *       <li>using the default format for the default <code>Locale</code></li>
    37   *       <li>using a specified pattern with the default <code>Locale</code></li>
    38   *       <li>using the default format for a specified <code>Locale</code></li>
    39   *       <li>using a specified pattern with a specified <code>Locale</code></li>
    40   *    </ul>
    41   *
    42   * <p>For each of the above mechanisms, conversion method (i.e the
    43   *    <code>validate</code> methods) implementations are provided which
    44   *    either use the default <code>TimeZone</code> or allow the
    45   *    <code>TimeZone</code> to be specified.</p>
    46   *
    47   * <p>Use one of the <code>isValid()</code> methods to just validate or
    48   *    one of the <code>validate()</code> methods to validate and receive a
    49   *    <i>converted</i> <code>Calendar</code> value.</p>
    50   *
    51   * <p>Implementations of the <code>validate()</code> method are provided
    52   *    to create <code>Calendar</code> objects for different <i>time zones</i>
    53   *    if the system default is not appropriate.</p>
    54   *
    55   * <p>Alternatively the CalendarValidator's <code>adjustToTimeZone()</code> method
    56   *    can be used to adjust the <code>TimeZone</code> of the <code>Calendar</code>
    57   *    object afterwards.</p>
    58   *
    59   * <p>Once a value has been sucessfully converted the following
    60   *    methods can be used to perform various date comparison checks:</p>
    61   *    <ul>
    62   *       <li><code>compareDates()</code> compares the day, month and
    63   *           year of two calendars, returing 0, -1 or +1 indicating
    64   *           whether the first date is equal, before or after the second.</li>
    65   *       <li><code>compareWeeks()</code> compares the week and
    66   *           year of two calendars, returing 0, -1 or +1 indicating
    67   *           whether the first week is equal, before or after the second.</li>
    68   *       <li><code>compareMonths()</code> compares the month and
    69   *           year of two calendars, returing 0, -1 or +1 indicating
    70   *           whether the first month is equal, before or after the second.</li>
    71   *       <li><code>compareQuarters()</code> compares the quarter and
    72   *           year of two calendars, returing 0, -1 or +1 indicating
    73   *           whether the first quarter is equal, before or after the second.</li>
    74   *       <li><code>compareYears()</code> compares the
    75   *           year of two calendars, returing 0, -1 or +1 indicating
    76   *           whether the first year is equal, before or after the second.</li>
    77   *    </ul>
    78   *
    79   * <p>So that the same mechanism used for parsing an <i>input</i> value
    80   *    for validation can be used to format <i>output</i>, corresponding
    81   *    <code>format()</code> methods are also provided. That is you can
    82   *    format either:</p>
    83   *    <ul>
    84   *       <li>using a specified pattern</li>
    85   *       <li>using the format for a specified <code>Locale</code></li>
    86   *       <li>using the format for the <i>default</i> <code>Locale</code></li>
    87   *    </ul>
    88   *
    89   * @version $Revision: 386637 $ $Date: 2006-03-17 13:22:26 +0000 (Fri, 17 Mar 2006) $
    90   * @since Validator 1.3.0
    91   */
    92  public class CalendarValidator extends AbstractCalendarValidator {
    93
    94      private static final CalendarValidator VALIDATOR = new CalendarValidator();
    95
    96      /***
    97       * Return a singleton instance of this validator.
    98       * @return A singleton instance of the CalendarValidator.
    99       */
    100     public static CalendarValidator getInstance() {
    101         return VALIDATOR;
    102     }
    103
    104     /***
    105      * Construct a <i>strict</i> instance with <i>short</i>
    106      * date style.
    107      */
    108     public CalendarValidator() {
    109         this(true, DateFormat.SHORT);
    110     }
    111
    112     /***
    113      * Construct an instance with the specified <i>strict</i>
    114      * and <i>date style</i> parameters.
    115      *
    116      * @param strict <code>true</code> if strict
    117      *        <code>Format</code> parsing should be used.
    118      * @param dateStyle the date style to use for Locale validation.
    119      */
    120     public CalendarValidator(boolean strict, int dateStyle) {
    121         super(strict, dateStyle, -1);
    122     }
    123
    124     /***
    125      * <p>Validate/convert a <code>Calendar</code> using the default
    126      *    <code>Locale</code> and <code>TimeZone</code>.
    127      *
    128      * @param value The value validation is being performed on.
    129      * @return The parsed <code>Calendar</code> if valid or <code>null</code>
    130      *  if invalid.
    131      */
    132     public Calendar validate(String value) {
    133         return (Calendar)parse(value, (String)null, (Locale)null, (TimeZone)null);
    134     }
    135
    136     /***
    137      * <p>Validate/convert a <code>Calendar</code> using the specified
    138      *    <code>TimeZone</code> and default <code>Locale</code>.
    139      *
    140      * @param value The value validation is being performed on.
    141      * @param timeZone The Time Zone used to parse the date, system default if null.
    142      * @return The parsed <code>Calendar</code> if valid or <code>null</code>
    143      *  if invalid.
    144      */
    145     public Calendar validate(String value, TimeZone timeZone) {
    146         return (Calendar)parse(value, (String)null, (Locale)null, timeZone);
    147     }
    148
    149     /***
    150      * <p>Validate/convert a <code>Calendar</code> using the specified
    151      *    <i>pattern</i> and default <code>TimeZone</code>.
    152      *
    153      * @param value The value validation is being performed on.
    154      * @param pattern The pattern used to validate the value against.
    155      * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
    156      */
    157     public Calendar validate(String value, String pattern) {
    158         return (Calendar)parse(value, pattern, (Locale)null, (TimeZone)null);
    159     }
    160
    161     /***
    162      * <p>Validate/convert a <code>Calendar</code> using the specified
    163      *    <i>pattern</i> and <code>TimeZone</code>.
    164      *
    165      * @param value The value validation is being performed on.
    166      * @param pattern The pattern used to validate the value against.
    167      * @param timeZone The Time Zone used to parse the date, system default if null.
    168      * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
    169      */
    170     public Calendar validate(String value, String pattern, TimeZone timeZone) {
    171         return (Calendar)parse(value, pattern, (Locale)null, timeZone);
    172     }
    173
    174     /***
    175      * <p>Validate/convert a <code>Calendar</code> using the specified
    176      *    <code>Locale</code> and default <code>TimeZone</code>.
    177      *
    178      * @param value The value validation is being performed on.
    179      * @param locale The locale to use for the date format, system default if null.
    180      * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
    181      */
    182     public Calendar validate(String value, Locale locale) {
    183         return (Calendar)parse(value, (String)null, locale, (TimeZone)null);
    184     }
    185
    186     /***
    187      * <p>Validate/convert a <code>Calendar</code> using the specified
    188      *    <code>Locale</code> and <code>TimeZone</code>.
    189      *
    190      * @param value The value validation is being performed on.
    191      * @param locale The locale to use for the date format, system default if null.
    192      * @param timeZone The Time Zone used to parse the date, system default if null.
    193      * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
    194      */
    195     public Calendar validate(String value, Locale locale, TimeZone timeZone) {
    196         return (Calendar)parse(value, (String)null, locale, timeZone);
    197     }
    198
    199     /***
    200      * <p>Validate/convert a <code>Calendar</code> using the specified pattern
    201      *    and <code>Locale</code> and the default <code>TimeZone</code>.
    202      *
    203      * @param value The value validation is being performed on.
    204      * @param pattern The pattern used to validate the value against, or the
    205      *        default for the <code>Locale</code> if <code>null</code>.
    206      * @param locale The locale to use for the date format, system default if null.
    207      * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
    208      */
    209     public Calendar validate(String value, String pattern, Locale locale) {
    210         return (Calendar)parse(value, pattern, locale, (TimeZone)null);
    211     }
    212
    213     /***
    214      * <p>Validate/convert a <code>Calendar</code> using the specified
    215      *    pattern, and <code>Locale</code> and <code>TimeZone</code>.
    216      *
    217      * @param value The value validation is being performed on.
    218      * @param pattern The pattern used to validate the value against, or the
    219      *        default for the <code>Locale</code> if <code>null</code>.
    220      * @param locale The locale to use for the date format, system default if null.
    221      * @param timeZone The Time Zone used to parse the date, system default if null.
    222      * @return The parsed <code>Calendar</code> if valid or <code>null</code> if invalid.
    223      */
    224     public Calendar validate(String value, String pattern, Locale locale, TimeZone timeZone) {
    225         return (Calendar)parse(value, pattern, locale, timeZone);
    226     }
    227
    228     /***
    229      * <p>Adjusts a Calendar's value to a different TimeZone.</p>
    230      *
    231      * @param value The value to adjust.
    232      * @param timeZone The new time zone to use to adjust the Calendar to.
    233      */
    234     public static void adjustToTimeZone(Calendar value, TimeZone timeZone) {
    235         if (value.getTimeZone().hasSameRules(timeZone)) {
    236             value.setTimeZone(timeZone);
    237         } else {
    238             int year   = value.get(Calendar.YEAR);
    239             int month  = value.get(Calendar.MONTH);
    240             int date   = value.get(Calendar.DATE);
    241             int hour   = value.get(Calendar.HOUR_OF_DAY);
    242             int minute = value.get(Calendar.MINUTE);
    243             value.setTimeZone(timeZone);
    244             value.set(year, month, date, hour, minute);
    245         }
    246     }
    247
    248     /***
    249      * <p>Compare Dates (day, month and year - not time).</p>
    250      *
    251      * @param value The <code>Calendar</code> value to check.
    252      * @param compare The <code>Calendar</code> to compare the value to.
    253      * @return Zero if the dates are equal, -1 if first
    254      * date is less than the seconds and +1 if the first
    255      * date is greater than.
    256      */
    257     public int compareDates(Calendar value, Calendar compare) {
    258         return compare(value, compare, Calendar.DATE);
    259     }
    260
    261     /***
    262      * <p>Compare Weeks (week and year).</p>
    263      *
    264      * @param value The <code>Calendar</code> value to check.
    265      * @param compare The <code>Calendar</code> to compare the value to.
    266      * @return Zero if the weeks are equal, -1 if first
    267      * parameter's week is less than the seconds and +1 if the first
    268      * parameter's week is greater than.
    269      */
    270     public int compareWeeks(Calendar value, Calendar compare) {
    271         return compare(value, compare, Calendar.WEEK_OF_YEAR);
    272     }
    273
    274     /***
    275      * <p>Compare Months (month and year).</p>
    276      *
    277      * @param value The <code>Calendar</code> value to check.
    278      * @param compare The <code>Calendar</code> to compare the value to.
    279      * @return Zero if the months are equal, -1 if first
    280      * parameter's month is less than the seconds and +1 if the first
    281      * parameter's month is greater than.
    282      */
    283     public int compareMonths(Calendar value, Calendar compare) {
    284         return compare(value, compare, Calendar.MONTH);
    285     }
    286
    287     /***
    288      * <p>Compare Quarters (quarter and year).</p>
    289      *
    290      * @param value The <code>Calendar</code> value to check.
    291      * @param compare The <code>Calendar</code> to check the value against.
    292      * @return Zero if the quarters are equal, -1 if first
    293      * parameter's quarter is less than the seconds and +1 if the first
    294      * parameter's quarter is greater than.
    295      */
    296     public int compareQuarters(Calendar value, Calendar compare) {
    297         return compareQuarters(value, compare, 1);
    298     }
    299
    300     /***
    301      * <p>Compare Quarters (quarter and year).</p>
    302      *
    303      * @param value The <code>Calendar</code> value to check.
    304      * @param compare The <code>Calendar</code> to compare the value to.
    305      * @param monthOfFirstQuarter The  month that the first quarter starts.
    306      * @return Zero if the quarters are equal, -1 if first
    307      * parameter's quarter is less than the seconds and +1 if the first
    308      * parameter's quarter is greater than.
    309      */
    310     public int compareQuarters(Calendar value, Calendar compare, int monthOfFirstQuarter) {
    311         return super.compareQuarters(value, compare, monthOfFirstQuarter);
    312     }
    313
    314     /***
    315      * <p>Compare Years.</p>
    316      *
    317      * @param value The <code>Calendar</code> value to check.
    318      * @param compare The <code>Calendar</code> to compare the value to.
    319      * @return Zero if the years are equal, -1 if first
    320      * parameter's year is less than the seconds and +1 if the first
    321      * parameter's year is greater than.
    322      */
    323     public int compareYears(Calendar value, Calendar compare) {
    324         return compare(value, compare, Calendar.YEAR);
    325     }
    326
    327     /***
    328      * <p>Convert the parsed <code>Date</code> to a <code>Calendar</code>.</p>
    329      *
    330      * @param value The parsed <code>Date</code> object created.
    331      * @param formatter The Format used to parse the value with.
    332      * @return The parsed value converted to a <code>Calendar</code>.
    333      */
    334     protected Object processParsedValue(Object value, Format formatter) {
    335         return ((DateFormat)formatter).getCalendar();
    336     }
    337
    338 }