CalendarValidator.java

  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. import java.text.DateFormat;
  19. import java.text.Format;
  20. import java.util.Calendar;
  21. import java.util.Locale;
  22. import java.util.TimeZone;

  23. /**
  24.  * <p><b>Calendar Validation</b> and Conversion routines (<code>java.util.Calendar</code>).</p>
  25.  *
  26.  * <p>This validator provides a number of methods for validating/converting
  27.  *    a <code>String</code> date value to a <code>java.util.Calendar</code> using
  28.  *    <code>java.text.DateFormat</code> to parse either:</p>
  29.  *    <ul>
  30.  *       <li>using the default format for the default <code>Locale</code></li>
  31.  *       <li>using a specified pattern with the default <code>Locale</code></li>
  32.  *       <li>using the default format for a specified <code>Locale</code></li>
  33.  *       <li>using a specified pattern with a specified <code>Locale</code></li>
  34.  *    </ul>
  35.  *
  36.  * <p>For each of the above mechanisms, conversion method (i.e the
  37.  *    <code>validate</code> methods) implementations are provided which
  38.  *    either use the default <code>TimeZone</code> or allow the
  39.  *    <code>TimeZone</code> to be specified.</p>
  40.  *
  41.  * <p>Use one of the <code>isValid()</code> methods to just validate or
  42.  *    one of the <code>validate()</code> methods to validate and receive a
  43.  *    <i>converted</i> <code>Calendar</code> value.</p>
  44.  *
  45.  * <p>Implementations of the <code>validate()</code> method are provided
  46.  *    to create <code>Calendar</code> objects for different <i>time zones</i>
  47.  *    if the system default is not appropriate.</p>
  48.  *
  49.  * <p>Alternatively the CalendarValidator's <code>adjustToTimeZone()</code> method
  50.  *    can be used to adjust the <code>TimeZone</code> of the <code>Calendar</code>
  51.  *    object afterwards.</p>
  52.  *
  53.  * <p>Once a value has been successfully converted the following
  54.  *    methods can be used to perform various date comparison checks:</p>
  55.  *    <ul>
  56.  *       <li><code>compareDates()</code> compares the day, month and
  57.  *           year of two calendars, returning 0, -1 or +1 indicating
  58.  *           whether the first date is equal, before or after the second.</li>
  59.  *       <li><code>compareWeeks()</code> compares the week and
  60.  *           year of two calendars, returning 0, -1 or +1 indicating
  61.  *           whether the first week is equal, before or after the second.</li>
  62.  *       <li><code>compareMonths()</code> compares the month and
  63.  *           year of two calendars, returning 0, -1 or +1 indicating
  64.  *           whether the first month is equal, before or after the second.</li>
  65.  *       <li><code>compareQuarters()</code> compares the quarter and
  66.  *           year of two calendars, returning 0, -1 or +1 indicating
  67.  *           whether the first quarter is equal, before or after the second.</li>
  68.  *       <li><code>compareYears()</code> compares the
  69.  *           year of two calendars, returning 0, -1 or +1 indicating
  70.  *           whether the first year is equal, before or after the second.</li>
  71.  *    </ul>
  72.  *
  73.  * <p>So that the same mechanism used for parsing an <i>input</i> value
  74.  *    for validation can be used to format <i>output</i>, corresponding
  75.  *    <code>format()</code> methods are also provided. That is you can
  76.  *    format either:</p>
  77.  *    <ul>
  78.  *       <li>using a specified pattern</li>
  79.  *       <li>using the format for a specified <code>Locale</code></li>
  80.  *       <li>using the format for the <i>default</i> <code>Locale</code></li>
  81.  *    </ul>
  82.  *
  83.  * @since 1.3.0
  84.  */
  85. public class CalendarValidator extends AbstractCalendarValidator {

  86.     private static final long serialVersionUID = 9109652318762134167L;

  87.     private static final CalendarValidator VALIDATOR = new CalendarValidator();

  88.     /**
  89.      * <p>Adjusts a Calendar's value to a different TimeZone.</p>
  90.      *
  91.      * @param value The value to adjust.
  92.      * @param timeZone The new time zone to use to adjust the Calendar to.
  93.      */
  94.     public static void adjustToTimeZone(final Calendar value, final TimeZone timeZone) {
  95.         if (value.getTimeZone().hasSameRules(timeZone)) {
  96.             value.setTimeZone(timeZone);
  97.         } else {
  98.             final int year = value.get(Calendar.YEAR);
  99.             final int month = value.get(Calendar.MONTH);
  100.             final int date = value.get(Calendar.DATE);
  101.             final int hour = value.get(Calendar.HOUR_OF_DAY);
  102.             final int minute = value.get(Calendar.MINUTE);
  103.             value.setTimeZone(timeZone);
  104.             value.set(year, month, date, hour, minute);
  105.         }
  106.     }

  107.     /**
  108.      * Gets the singleton instance of this validator.
  109.      * @return A singleton instance of the CalendarValidator.
  110.      */
  111.     public static CalendarValidator getInstance() {
  112.         return VALIDATOR;
  113.     }

  114.     /**
  115.      * Constructs a <i>strict</i> instance with <i>short</i>
  116.      * date style.
  117.      */
  118.     public CalendarValidator() {
  119.         this(true, DateFormat.SHORT);
  120.     }

  121.     /**
  122.      * Constructs an instance with the specified <i>strict</i>
  123.      * and <i>date style</i> parameters.
  124.      *
  125.      * @param strict {@code true} if strict
  126.      *        <code>Format</code> parsing should be used.
  127.      * @param dateStyle the date style to use for Locale validation.
  128.      */
  129.     public CalendarValidator(final boolean strict, final int dateStyle) {
  130.         super(strict, dateStyle, -1);
  131.     }

  132.     /**
  133.      * <p>Compare Dates (day, month and year - not time).</p>
  134.      *
  135.      * @param value The <code>Calendar</code> value to check.
  136.      * @param compare The <code>Calendar</code> to compare the value to.
  137.      * @return Zero if the dates are equal, -1 if first
  138.      * date is less than the seconds and +1 if the first
  139.      * date is greater than.
  140.      */
  141.     public int compareDates(final Calendar value, final Calendar compare) {
  142.         return compare(value, compare, Calendar.DATE);
  143.     }

  144.     /**
  145.      * <p>Compare Months (month and year).</p>
  146.      *
  147.      * @param value The <code>Calendar</code> value to check.
  148.      * @param compare The <code>Calendar</code> to compare the value to.
  149.      * @return Zero if the months are equal, -1 if first
  150.      * parameter's month is less than the seconds and +1 if the first
  151.      * parameter's month is greater than.
  152.      */
  153.     public int compareMonths(final Calendar value, final Calendar compare) {
  154.         return compare(value, compare, Calendar.MONTH);
  155.     }

  156.     /**
  157.      * <p>Compare Quarters (quarter and year).</p>
  158.      *
  159.      * @param value The <code>Calendar</code> value to check.
  160.      * @param compare The <code>Calendar</code> to check the value against.
  161.      * @return Zero if the quarters are equal, -1 if first
  162.      * parameter's quarter is less than the seconds and +1 if the first
  163.      * parameter's quarter is greater than.
  164.      */
  165.     public int compareQuarters(final Calendar value, final Calendar compare) {
  166.         return compareQuarters(value, compare, 1);
  167.     }

  168.     /**
  169.      * <p>Compare Quarters (quarter and year).</p>
  170.      *
  171.      * @param value The <code>Calendar</code> value to check.
  172.      * @param compare The <code>Calendar</code> to compare the value to.
  173.      * @param monthOfFirstQuarter The  month that the first quarter starts.
  174.      * @return Zero if the quarters are equal, -1 if first
  175.      * parameter's quarter is less than the seconds and +1 if the first
  176.      * parameter's quarter is greater than.
  177.      */
  178.     @Override
  179.     public int compareQuarters(final Calendar value, final Calendar compare, final int monthOfFirstQuarter) {
  180.         return super.compareQuarters(value, compare, monthOfFirstQuarter);
  181.     }

  182.     /**
  183.      * <p>Compare Weeks (week and year).</p>
  184.      *
  185.      * @param value The <code>Calendar</code> value to check.
  186.      * @param compare The <code>Calendar</code> to compare the value to.
  187.      * @return Zero if the weeks are equal, -1 if first
  188.      * parameter's week is less than the seconds and +1 if the first
  189.      * parameter's week is greater than.
  190.      */
  191.     public int compareWeeks(final Calendar value, final Calendar compare) {
  192.         return compare(value, compare, Calendar.WEEK_OF_YEAR);
  193.     }

  194.     /**
  195.      * <p>Compare Years.</p>
  196.      *
  197.      * @param value The <code>Calendar</code> value to check.
  198.      * @param compare The <code>Calendar</code> to compare the value to.
  199.      * @return Zero if the years are equal, -1 if first
  200.      * parameter's year is less than the seconds and +1 if the first
  201.      * parameter's year is greater than.
  202.      */
  203.     public int compareYears(final Calendar value, final Calendar compare) {
  204.         return compare(value, compare, Calendar.YEAR);
  205.     }

  206.     /**
  207.      * <p>Convert the parsed <code>Date</code> to a <code>Calendar</code>.</p>
  208.      *
  209.      * @param value The parsed <code>Date</code> object created.
  210.      * @param formatter The Format used to parse the value with.
  211.      * @return The parsed value converted to a <code>Calendar</code>.
  212.      */
  213.     @Override
  214.     protected Object processParsedValue(final Object value, final Format formatter) {
  215.         return ((DateFormat) formatter).getCalendar();
  216.     }

  217.     /**
  218.      * <p>Validate/convert a <code>Calendar</code> using the default
  219.      *    <code>Locale</code> and <code>TimeZone</code>.
  220.      *
  221.      * @param value The value validation is being performed on.
  222.      * @return The parsed <code>Calendar</code> if valid or {@code null}
  223.      *  if invalid.
  224.      */
  225.     public Calendar validate(final String value) {
  226.         return (Calendar) parse(value, (String) null, (Locale) null, (TimeZone) null);
  227.     }

  228.     /**
  229.      * <p>Validate/convert a <code>Calendar</code> using the specified
  230.      *    <code>Locale</code> and default <code>TimeZone</code>.
  231.      *
  232.      * @param value The value validation is being performed on.
  233.      * @param locale The locale to use for the date format, system default if null.
  234.      * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid.
  235.      */
  236.     public Calendar validate(final String value, final Locale locale) {
  237.         return (Calendar) parse(value, (String) null, locale, (TimeZone) null);
  238.     }

  239.     /**
  240.      * <p>Validate/convert a <code>Calendar</code> using the specified
  241.      *    <code>Locale</code> and <code>TimeZone</code>.
  242.      *
  243.      * @param value The value validation is being performed on.
  244.      * @param locale The locale to use for the date format, system default if null.
  245.      * @param timeZone The Time Zone used to parse the date, system default if null.
  246.      * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid.
  247.      */
  248.     public Calendar validate(final String value, final Locale locale, final TimeZone timeZone) {
  249.         return (Calendar) parse(value, (String) null, locale, timeZone);
  250.     }

  251.     /**
  252.      * <p>Validate/convert a <code>Calendar</code> using the specified
  253.      *    <i>pattern</i> and default <code>TimeZone</code>.
  254.      *
  255.      * @param value The value validation is being performed on.
  256.      * @param pattern The pattern used to validate the value against.
  257.      * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid.
  258.      */
  259.     public Calendar validate(final String value, final String pattern) {
  260.         return (Calendar) parse(value, pattern, (Locale) null, (TimeZone) null);
  261.     }

  262.     /**
  263.      * <p>Validate/convert a <code>Calendar</code> using the specified pattern
  264.      *    and <code>Locale</code> and the default <code>TimeZone</code>.
  265.      *
  266.      * @param value The value validation is being performed on.
  267.      * @param pattern The pattern used to validate the value against, or the
  268.      *        default for the <code>Locale</code> if {@code null}.
  269.      * @param locale The locale to use for the date format, system default if null.
  270.      * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid.
  271.      */
  272.     public Calendar validate(final String value, final String pattern, final Locale locale) {
  273.         return (Calendar) parse(value, pattern, locale, (TimeZone) null);
  274.     }

  275.     /**
  276.      * <p>Validate/convert a <code>Calendar</code> using the specified
  277.      *    pattern, and <code>Locale</code> and <code>TimeZone</code>.
  278.      *
  279.      * @param value The value validation is being performed on.
  280.      * @param pattern The pattern used to validate the value against, or the
  281.      *        default for the <code>Locale</code> if {@code null}.
  282.      * @param locale The locale to use for the date format, system default if null.
  283.      * @param timeZone The Time Zone used to parse the date, system default if null.
  284.      * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid.
  285.      */
  286.     public Calendar validate(final String value, final String pattern, final Locale locale, final TimeZone timeZone) {
  287.         return (Calendar) parse(value, pattern, locale, timeZone);
  288.     }

  289.     /**
  290.      * <p>Validate/convert a <code>Calendar</code> using the specified
  291.      *    <i>pattern</i> and <code>TimeZone</code>.
  292.      *
  293.      * @param value The value validation is being performed on.
  294.      * @param pattern The pattern used to validate the value against.
  295.      * @param timeZone The Time Zone used to parse the date, system default if null.
  296.      * @return The parsed <code>Calendar</code> if valid or {@code null} if invalid.
  297.      */
  298.     public Calendar validate(final String value, final String pattern, final TimeZone timeZone) {
  299.         return (Calendar) parse(value, pattern, (Locale) null, timeZone);
  300.     }

  301.     /**
  302.      * <p>Validate/convert a <code>Calendar</code> using the specified
  303.      *    <code>TimeZone</code> and default <code>Locale</code>.
  304.      *
  305.      * @param value The value validation is being performed on.
  306.      * @param timeZone The Time Zone used to parse the date, system default if null.
  307.      * @return The parsed <code>Calendar</code> if valid or {@code null}
  308.      *  if invalid.
  309.      */
  310.     public Calendar validate(final String value, final TimeZone timeZone) {
  311.         return (Calendar) parse(value, (String) null, (Locale) null, timeZone);
  312.     }

  313. }