View Javadoc

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