jp.co.ctc_g.jfw.core.util.Dates.java Source code

Java tutorial

Introduction

Here is the source code for jp.co.ctc_g.jfw.core.util.Dates.java

Source

/*
 * Copyright (c) 2013 ITOCHU Techno-Solutions Corporation.
 *
 * Licensed 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 jp.co.ctc_g.jfw.core.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

import jp.co.ctc_g.jfw.core.internal.InternalException;
import jp.co.ctc_g.jfw.core.internal.InternalMessages;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>
 * ????????????
 * </p>
 * @author ITOCHU Techno-Solutions Corporation.
 */
public final class Dates {

    private static final Log L = LogFactory.getLog(Dates.class);
    private static final ResourceBundle R = InternalMessages.getBundle(Dates.class);
    /**
     * .
     */
    public static final DateType YEAR = new DateType("YEAR");
    /**
     * .
     */
    public static final DateType MONTH = new DateType("MONTH");
    /**
     * .
     */
    public static final DateType DAY = new DateType("DAY");
    /**
     * .
     */
    public static final DateType HOUR = new DateType("HOUR");
    /**
     * .
     */
    public static final DateType MINUTE = new DateType("MINUTE");
    /**
     * .
     */
    public static final DateType SECOND = new DateType("SECOND");
    /**
     * .
     */
    public static final DateType MSEC = new DateType("MSEC");
    /**
     * .
     */
    public static final int NANOS_2_MSEC = 1000000;
    /**
     * Calendar??int?.
     */
    static final int[] CALENDAR_MONTH = new int[] { Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH,
            Calendar.APRIL, Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST, Calendar.SEPTEMBER,
            Calendar.OCTOBER, Calendar.NOVEMBER, Calendar.DECEMBER };
    /**
     * Calendar?????int?.
     */
    private static final int[] REAL_MONTH = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    /**
     * ???????.
     */
    private static final int[] MAX_DATE = new int[] { 9999, 12, 31 };
    /**
     * ????????.
     */
    private static final int[] MIN_DATE = new int[] { 1, 1, 1 };
    /**
     * ???????.
     */
    private static final int[] MAX_TIMES = new int[] { 23, 59, 59 };
    /**
     * ????????.
     */
    private static final int[] MIN_TIMES = new int[] { 0, 0, 0 };
    /**
     * ?????????.
     */
    private static final int[] DAY_OF_MONTH = new int[] { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

    private Dates() {
    }

    /**
     * ??????????
     * {@link Date}????
     * ?<code>null</code>???????????
     * ???<code>null</code>????
     * ?{@link SimpleDateFormat}????
     * ??????????
     * ?????????null????
     * @param source ??
     * @param pattern 
     * @return ????{@link Date}
     */
    public static Date makeFrom(String source, String pattern) {
        if (Strings.isEmpty(source) || Strings.isEmpty(pattern))
            return null;
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        sdf.setLenient(true);
        ParsePosition pos = new ParsePosition(0);
        Date date = sdf.parse(source, pos);
        if (pos.getErrorIndex() != -1 && L.isDebugEnabled()) {
            Map<String, Object> replace = new HashMap<String, Object>(3);
            replace.put("pattern", pattern);
            replace.put("index", pos.getErrorIndex() + 1);
            replace.put("target", source);
            L.debug(Strings.substitute(R.getString("D-UTIL#0002"), replace));
        }
        return date;
    }

    /**
     * ????????
     * @param year 
     * @param month 
     * @return 
     */
    public static Date makeFrom(int year, int month) {
        return makeFrom(year, month, 1, 0, 0, 0, 0);
    }

    /**
     * ????????
     * @param year 
     * @param month 
     * @param day 
     * @return 
     */
    public static Date makeFrom(int year, int month, int day) {
        return makeFrom(year, month, day, 0, 0, 0, 0);
    }

    /**
     * ????????
     * @param year 
     * @param month 
     * @param day 
     * @param hourOfDay 
     * @return 
     */
    public static Date makeFrom(int year, int month, int day, int hourOfDay) {
        return makeFrom(year, month, day, hourOfDay, 0, 0, 0);
    }

    /**
     * ????????
     * @param year 
     * @param month 
     * @param day 
     * @param hourOfDay 
     * @param minute 
     * @return 
     */
    public static Date makeFrom(int year, int month, int day, int hourOfDay, int minute) {
        return makeFrom(year, month, day, hourOfDay, minute, 0, 0);
    }

    /**
     * ????????
     * @param year 
     * @param month 
     * @param day 
     * @param hourOfDay 
     * @param minute 
     * @param second 
     * @return 
     */
    public static Date makeFrom(int year, int month, int day, int hourOfDay, int minute, int second) {
        return makeFrom(year, month, day, hourOfDay, minute, second, 0);
    }

    /**
     * ????????
     * @param year 
     * @param month 
     * @param day 
     * @param hourOfDay 
     * @param minute 
     * @param second 
     * @param millis 
     * @return 
     */
    public static Date makeFrom(int year, int month, int day, int hourOfDay, int minute, int second, int millis) {
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.set(year, month - 1 /* zero origin */, day, hourOfDay, minute, second);
        calendar.set(Calendar.MILLISECOND, millis);
        return calendar.getTime();
    }

    /**
     * ????
     * @param date ??
     * @return ??
     */
    public static Date nextYear(Date date) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, 1);
        return calendar.getTime();
    }

    /**
     * ????
     * @param date ??
     * @return ??
     */
    public static Date nextMonth(Date date) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        return calendar.getTime();
    }

    /**
     * ????
     * @param date ??
     * @return ??
     */
    public static Date nextDay(Date date) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    /**
     * ?????
     * @param date ??
     * @return ??
     */
    public static Date previousYear(Date date) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, -1);
        return calendar.getTime();
    }

    /**
     * ?????
     * @param date ??
     * @return ??
     */
    public static Date previousMonth(Date date) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        return calendar.getTime();
    }

    /**
     * ?????
     * @param date ??
     * @return ??
     */
    public static Date previousDay(Date date) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    /**
     * ????
     * @param date ??
     * @return 
     */
    public static int getYear(Date date) {
        if (date == null)
            return -1;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * ????
     * ?????1???1??2???2????
     * @param date ??
     * @return 
     */
    public static int getMonth(Date date) {
        if (date == null)
            return -1;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * ????
     * @param date ??
     * @return 
     */
    public static int getDay(Date date) {
        if (date == null)
            return -1;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * ????
     * @param date ??
     * @return 
     */
    public static int getDayOfWeek(Date date) {
        if (date == null)
            return -1;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * ?????????
     * @param date ??
     * @return ?????
     */
    public static int lastDay(Date date) {
        if (date == null)
            return -1;
        Calendar calendar = Calendar.getInstance();
        calendar.setLenient(true);
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * ??????????.
     * @param year ?
     * @return ????????true? ????????false???.
     */
    public static boolean isLeapYear(int year) {

        return ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0));
    }

    /**
     * ???????????.
     * @param year ?
     * @param month ?
     * @param day ?
     * @return ??????true? ????????false???.
     */
    public static boolean isDate(int year, int month, int day) {

        return enableRange(MAX_DATE, MIN_DATE, new int[] { year, month, day })
                && enableDayOfMonth(year, month, day);
    }

    /**
     * ????????.
     * @param hour ?
     * @param minutes ?
     * @param second ?
     * @return ??????true? ????????false???.
     */
    public static boolean isTime(int hour, int minutes, int second) {

        return enableRange(MAX_TIMES, MIN_TIMES, new int[] { hour, minutes, second });
    }

    /**
     * ?????.
     * @return ??
     */
    public static int getYear() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.YEAR);
    }

    /**
     * ?????.
     * @return ??
     */
    public static int getMonth() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return Dates.toRealMonth(currentCalendar.get(Calendar.MONTH));
    }

    /**
     * Calendar???????.
     * @return ??
     */
    public static int getCalendarMonth() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.MONTH);
    }

    /**
     * ?????.
     * @return ??
     */
    public static int getDay() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.DATE);
    }

    /**
     * ?????.
     * @return ??
     */
    public static int getHour() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * ?????.
     * @return ??
     */
    public static int getMinutes() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.MINUTE);
    }

    /**
     * ?????.
     * @return ??
     */
    public static int getMillisecond() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.MILLISECOND);
    }

    /**
     * ?????.
     * @return ??
     */
    public static int getSecond() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.SECOND);
    }

    /**
     * ??????????.
     * @return ????????
     */
    public static int getDayOfYear() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.DAY_OF_YEAR);
    }

    /**
     * ???.
     * @return ???java.util.Calendar?
     */
    public static int getDayOfWeek() {

        Calendar currentCalendar = Dates.getCalendarInstance();
        return currentCalendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * ??{@link java.sql.Timestamp java.sql.Timestamp}???
     * {@link java.util.Date java.util.Date} ???.
     * @param date 
     * @return ???{@link java.util.Date java.util.Date}
     */
    public static java.util.Date getDate(Timestamp date) {

        return new java.util.Date(date.getTime());
    }

    /**
     * ?????{@link java.util.Date java.util.Date}???.
     * @return ???{@link java.util.Date java.util.Date}
     */
    public static java.util.Date getDate() {

        return new java.util.Date(System.currentTimeMillis());
    }

    /**
     * ?????{@link java.util.Date java.util.Date}???.
     * @param year 
     * @param month 
     * @param day 
     * @return ???{@link java.util.Date java.util.Date}
     */
    public static java.util.Date getDate(int year, int month, int day) {

        return new java.util.Date(Dates.getTime(year, month, day));
    }

    /**
     * ?????{@link java.util.Date java.util.Date}???.
     * @param year 
     * @param month 
     * @param day 
     * @param hour 
     * @param minutes 
     * @param second 
     * @return ????{@link java.util.Date java.util.Date}
     */
    public static java.util.Date getDate(int year, int month, int day, int hour, int minutes, int second) {

        return new java.util.Date(Dates.getTime(year, month, day, hour, minutes, second));
    }

    /**
     * ??{@link java.util.Date java.util.Date}???{@link java.sql.Date java.sql.Date}???.
     * @param date 
     * @return ???{@link java.sql.Date java.sql.Date}
     */
    public static java.sql.Date getSqlDate(java.util.Date date) {

        return new java.sql.Date(date.getTime());
    }

    /**
     * ?????{@link java.sql.Date java.sql.Date}???.
     * @return ???{@link java.sql.Date java.sql.Date}
     */
    public static java.sql.Date getSqlDate() {

        return new java.sql.Date(System.currentTimeMillis());
    }

    /**
     * ?????java.sql.Time???.
     * @return ???java.sql.Time
     */
    public static Time getSqlTime() {

        return new Time(System.currentTimeMillis());
    }

    /**
     * ??{@link java.util.Date java.util.Date} ?{@link java.sql.Timestamp java.sql.Timestamp}???.
     * @param date 
     * @return ????{@link java.sql.Timestamp java.sql.Timestamp}
     */
    public static Timestamp getSqlTimestamp(java.util.Date date) {

        return new Timestamp(date.getTime());
    }

    /**
     * ????{@link java.sql.Timestamp java.sql.Timestamp}???.
     * @return ????{@link java.sql.Timestamp java.sql.Timestamp}
     */
    public static Timestamp getSqlTimestamp() {

        return new Timestamp(System.currentTimeMillis());
    }

    /**
     * ?????{@link java.sql.Date java.sql.Date}???.
     * @param year 
     * @param month 
     * @param day 
     * @return ????{@link java.sql.Date java.sql.Date}
     */
    public static java.sql.Date getSqlDate(int year, int month, int day) {

        return new java.sql.Date(Dates.getTime(year, month, day));
    }

    /**
     * ?????java.sql.Time???.
     * @param hour 
     * @param minutes 
     * @param second 
     * @return ????java.sql.Time
     */
    public static Time getSqlTime(int hour, int minutes, int second) {

        Calendar currentCalendar = Dates.getCalendarInstance();
        currentCalendar.set(Dates.getYear(), Dates.getMonth(), Dates.getDay(), hour, minutes, second);
        return new Time(currentCalendar.getTime().getTime());
    }

    /**
     * ??????{@link java.sql.Timestamp java.sql.Timestamp}???.
     * @param year 
     * @param month 
     * @param day 
     * @param hour 
     * @param minutes 
     * @param second 
     * @return ????{@link java.sql.Timestamp java.sql.Timestamp}
     */
    public static Timestamp getSqlTimestamp(int year, int month, int day, int hour, int minutes, int second) {

        return new Timestamp(Dates.getTime(year, month, day, hour, minutes, second));
    }

    /**
     * ???long?????.
     * @param year 
     * @param month 
     * @param day 
     * @return ?long??
     */
    public static long getTime(int year, int month, int day) {

        return Dates.getTime(year, month, day, 0, 0, 0);
    }

    /**
     * ????long?????.
     * @param year 
     * @param month 
     * @param day 
     * @param hour 
     * @param minutes 
     * @param second 
     * @return ??long??
     */
    public static long getTime(int year, int month, int day, int hour, int minutes, int second) {

        Calendar currentCalendar = Dates.getCalendarInstance(year, month, day, hour, minutes, second);
        currentCalendar.set(Calendar.MILLISECOND, 0);
        return currentCalendar.getTime().getTime();
    }

    /**
     * ?????.
     * @return Calendar?
     */
    public static Calendar getCalendarInstance() {

        return Calendar.getInstance();
    }

    /**
     * ??????.
     * @param year 
     * @param month 
     * @param day 
     * @param hour 
     * @param minutes 
     * @param second 
     * @return Calendar?
     */
    public static Calendar getCalendarInstance(int year, int month, int day, int hour, int minutes, int second) {

        Calendar currentCalendar = Dates.getCalendarInstance();
        currentCalendar.set(year, Dates.toCalendarMonth(month), day, hour, minutes, second);
        currentCalendar.set(Calendar.MILLISECOND, 0);
        return currentCalendar;
    }

    /**
     * ??????.
     * @param date 
     * @return ??
     */
    public static Calendar getCalendarInstance(Date date) {

        Calendar currentCalendar = Dates.getCalendarInstance();
        currentCalendar.setTime(date);
        return currentCalendar;
    }

    /**
     * Calendar???????????.
     * @param value {@link java.util.Calendar#get(int) Calendar#get(Calendar.MONTH)}????
     * @return ?112
     */
    public static int toRealMonth(int value) {

        for (int index = 0; index <= Dates.CALENDAR_MONTH.length - 1; index++) {
            if (Dates.CALENDAR_MONTH[index] == value) {
                return Dates.REAL_MONTH[index];
            }
        }
        throw new IllegalArgumentException("can use the value of 0 to 11. [" + String.valueOf(value) + "]");
    }

    /**
     * ??Calendar???????.
     * @param value ?112
     * @return Calendar??
     */
    public static int toCalendarMonth(int value) {

        return Dates.CALENDAR_MONTH[value - 1];
    }

    /**
     * ??????????.<br>
     * ??{#difference(long, long) difference(long, long)} ???????????.
     * @param date ?
     * @return ???
     */
    public static long difference(long date) {

        return Dates.getDate().getTime() - date;
    }

    /**
     * ??????????.<br>
     * ??{#difference({@link java.util.Date java.util.Date},
     * {@link java.util.Date java.util.Date}) difference(Date, Date)} ???????????.
     * @param date ?
     * @return ???
     */
    public static long difference(java.util.Date date) {

        return Dates.getDate().getTime() - date.getTime();
    }

    /**
     * ??????????.<br>
     * ??{#difference({@link java.sql.Timestamp java.sql.Timestamp},
     * {@link java.sql.Timestamp java.sql.Timestamp}) difference(Date, Date)}
     * ???????????.
     * @param date ?
     * @return ???
     */
    public static long difference(Timestamp date) {

        return Dates.getDate().getTime() - date.getTime();
    }

    /**
     * ??????????.
     * @param date1 ?
     * @param date2 ?
     * @return ???
     */
    public static long difference(long date1, long date2) {

        return date2 - date1;
    }

    /**
     * ??????????.
     * @param date1 ?
     * @param date2 ?
     * @return ???
     */
    public static long difference(java.util.Date date1, java.util.Date date2) {

        return date2.getTime() - date1.getTime();
    }

    /**
     * ??????????.
     * @param date1 ?
     * @param date2 ?
     * @return ???
     */
    public static long difference(Timestamp date1, Timestamp date2) {

        return date2.getTime() - date1.getTime();
    }

    /**
     * <ul>
     * ???????.
     * </ul>
     * @param dateClass java.util.Date?
     * @param millis 
     * @return date ??date
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected static Date instantiateDate(Class dateClass, long millis) {

        java.util.Date retObj = null;
        Constructor constructor = null;

        try {
            constructor = dateClass.getConstructor(new Class[] { long.class });
            retObj = (java.util.Date) constructor.newInstance(new Object[] { new Long(millis) });

        } catch (SecurityException e) {
            throw new InternalException(Dates.class, "E-UTIL#0035", e);
        } catch (NoSuchMethodException e) {
            throw new InternalException(Dates.class, "E-UTIL#0035", e);
        } catch (IllegalArgumentException e) {
            throw new InternalException(Dates.class, "E-UTIL#0035", e);
        } catch (InstantiationException e) {
            throw new InternalException(Dates.class, "E-UTIL#0035", e);
        } catch (IllegalAccessException e) {
            throw new InternalException(Dates.class, "E-UTIL#0035", e);
        } catch (InvocationTargetException e) {
            throw new InternalException(Dates.class, "E-UTIL#0035", e);
        }

        return retObj;
    }

    /**
     * ????????.
     * @param date ?
     * @param inclement ?.????????.
     * @return ??
     */
    public static Date addYear(Date date, int inclement) {

        if (inclement == 0) {
            return date;
        }
        Calendar currentCalendar = Dates.getCalendarInstance(date);
        currentCalendar.set(currentCalendar.get(Calendar.YEAR) + inclement, currentCalendar.get(Calendar.MONTH),
                currentCalendar.get(Calendar.DATE), currentCalendar.get(Calendar.HOUR_OF_DAY),
                currentCalendar.get(Calendar.MINUTE), currentCalendar.get(Calendar.SECOND));

        long time = currentCalendar.getTimeInMillis();

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), time);
    }

    /**
     * ????????.<br>
     * ???????????????.<br>
     * :531?1??630????.
     * @param date ?
     * @param inclement ?.????????.
     * @return ??
     */
    public static Date addMonth(Date date, int inclement) {

        if (inclement == 0) {
            return date;
        }
        Calendar currentCalendar = Dates.getCalendarInstance(date);
        int year = currentCalendar.get(Calendar.YEAR);
        int calendarMonth = currentCalendar.get(Calendar.MONTH);
        int month = Dates.toRealMonth(calendarMonth);
        month += inclement;
        for (; (month) <= 0 || (month) >= 13;) {
            if ((month) >= 13) {
                year++;
                month -= 12;
            } else {
                year--;
                month += 12;
            }
        }
        int day = currentCalendar.get(Calendar.DATE);
        int dayOfMonth = DAY_OF_MONTH[calendarMonth];
        if (day == dayOfMonth) {
            Date firstDate = Dates.getDate(year, month, 1);
            Date endOfMonth = Dates.endOfMonth(firstDate);
            Calendar inclementCalendar = Dates.getCalendarInstance(endOfMonth);
            day = inclementCalendar.get(Calendar.DATE);
        }
        currentCalendar.set(year, Dates.toCalendarMonth(month), day, currentCalendar.get(Calendar.HOUR_OF_DAY),
                currentCalendar.get(Calendar.MINUTE), currentCalendar.get(Calendar.SECOND));

        long time = currentCalendar.getTimeInMillis();

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), time);
    }

    /**
     * ????????.
     * @param date ?
     * @param inclement ?.????????.
     * @return ??
     */
    public static Date addDay(Date date, int inclement) {

        if (inclement == 0) {
            return date;
        }
        Calendar currentCalendar = Dates.getCalendarInstance(date);
        int year = currentCalendar.get(Calendar.YEAR);
        int month = Dates.toRealMonth(currentCalendar.get(Calendar.MONTH));
        int day = currentCalendar.get(Calendar.DATE);
        if (inclement >= 0) {
            for (int index = 0; index < inclement; index++) {
                day++;
                if (!enableDayOfMonth(year, month, day)) {
                    day = 1;
                    month++;
                    if (month >= 13 || !enableDayOfMonth(year, month, day)) {
                        month = 1;
                        year++;
                    }
                }
            }
        } else {
            for (int index = inclement; index < 0; index++) {
                day--;
                if (day <= 0) {
                    month--;
                    if (month <= 0) {
                        year--;
                        if (year <= 0) {
                            throw new InternalException(Dates.class, "E-UTIL#0036");
                        } else {
                            month = 12;
                            day = DAY_OF_MONTH[11];
                        }
                    } else {
                        day = DAY_OF_MONTH[month - 1];
                        if (!isLeapYear(year) && month == 2) {
                            day--;
                        }
                    }
                }
            }
        }
        currentCalendar.set(year, Dates.toCalendarMonth(month), day, currentCalendar.get(Calendar.HOUR_OF_DAY),
                currentCalendar.get(Calendar.MINUTE), currentCalendar.get(Calendar.SECOND));

        long time = currentCalendar.getTimeInMillis();

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), time);

    }

    /**
     * ????????.
     * @param date ?
     * @param inclement ?.????????.
     * @return ??
     */
    public static Date addHour(Date date, int inclement) {

        if (inclement == 0) {
            return date;
        }
        Calendar currentCalendar = Dates.getCalendarInstance(date);
        int year = currentCalendar.get(Calendar.YEAR);
        int month = Dates.toRealMonth(currentCalendar.get(Calendar.MONTH));
        int day = currentCalendar.get(Calendar.DATE);
        int hour = currentCalendar.get(Calendar.HOUR_OF_DAY);
        if (inclement >= 0) {
            for (int index = 0; index < inclement; index++) {
                hour++;
                if (hour >= 24) {
                    hour = 0;
                    day++;
                    if (!enableDayOfMonth(year, month, day)) {
                        day = 1;
                        month++;
                        if (month >= 13 || !enableDayOfMonth(year, month, day)) {
                            month = 1;
                            year++;
                        }
                    }
                }
            }
        } else {
            for (int index = inclement; index < 0; index++) {
                hour--;
                if (hour < 0) {
                    hour = 23;
                    day--;
                    if (day <= 0) {
                        month--;
                        if (month <= 0) {
                            year--;
                            if (year <= 0) {
                                throw new InternalException(Dates.class, "E-UTIL#0036");
                            } else {
                                month = 12;
                                day = DAY_OF_MONTH[11];
                            }
                        } else {
                            day = DAY_OF_MONTH[month - 1];
                            if (!isLeapYear(year) && month == 2) {
                                day--;
                            }
                        }
                    }
                }
            }
        }
        currentCalendar.set(year, Dates.toCalendarMonth(month), day, hour, currentCalendar.get(Calendar.MINUTE),
                currentCalendar.get(Calendar.SECOND));

        long time = currentCalendar.getTimeInMillis();

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), time);

    }

    /**
     * ????????.
     * @param date ?
     * @param inclement ?.????????.
     * @return ??
     */
    public static Date addMinute(Date date, int inclement) {

        if (inclement == 0) {
            return date;
        }
        Calendar currentCalendar = Dates.getCalendarInstance(date);
        int year = currentCalendar.get(Calendar.YEAR);
        int month = Dates.toRealMonth(currentCalendar.get(Calendar.MONTH));
        int day = currentCalendar.get(Calendar.DATE);
        int hour = currentCalendar.get(Calendar.HOUR_OF_DAY);
        int minute = currentCalendar.get(Calendar.MINUTE);
        if (inclement >= 0) {
            for (int index = 0; index < inclement; index++) {
                minute++;
                if (minute >= 60) {
                    minute = 0;
                    hour++;
                    if (hour >= 24) {
                        hour = 0;
                        day++;
                        if (!enableDayOfMonth(year, month, day)) {
                            day = 1;
                            month++;
                            if (month >= 13 || !enableDayOfMonth(year, month, day)) {
                                month = 1;
                                year++;
                            }
                        }
                    }
                }
            }
        } else {
            for (int index = inclement; index < 0; index++) {
                minute--;
                if (minute < 0) {
                    minute = 59;
                    hour--;
                    if (hour < 0) {
                        hour = 23;
                        day--;
                        if (day <= 0) {
                            month--;
                            if (month <= 0) {
                                year--;
                                if (year <= 0) {
                                    throw new InternalException(Dates.class, "E-UTIL#0036");
                                } else {
                                    month = 12;
                                    day = DAY_OF_MONTH[11];
                                }
                            } else {
                                day = DAY_OF_MONTH[month - 1];
                                if (!isLeapYear(year) && month == 2) {
                                    day--;
                                }
                            }
                        }
                    }
                }
            }
        }
        currentCalendar.set(year, Dates.toCalendarMonth(month), day, hour, minute,
                currentCalendar.get(Calendar.SECOND));

        long time = currentCalendar.getTimeInMillis();

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), time);

    }

    /**
     * ????????.
     * @param date ?
     * @param inclement ?.????????.
     * @return ??
     */
    public static Date addSecond(Date date, int inclement) {

        if (inclement == 0) {
            return date;
        }
        Calendar currentCalendar = Dates.getCalendarInstance(date);
        int year = currentCalendar.get(Calendar.YEAR);
        int month = Dates.toRealMonth(currentCalendar.get(Calendar.MONTH));
        int day = currentCalendar.get(Calendar.DATE);
        int hour = currentCalendar.get(Calendar.HOUR_OF_DAY);
        int minute = currentCalendar.get(Calendar.MINUTE);
        int second = currentCalendar.get(Calendar.SECOND);
        if (inclement >= 0) {
            for (int index = 0; index < inclement; index++) {
                second++;
                if (second >= 60) {
                    second = 0;
                    minute++;
                    if (minute >= 60) {
                        minute = 0;
                        hour++;
                        if (hour >= 24) {
                            hour = 0;
                            day++;
                            if (!enableDayOfMonth(year, month, day)) {
                                day = 1;
                                month++;
                                if (month >= 13 || !enableDayOfMonth(year, month, day)) {
                                    month = 1;
                                    year++;
                                }
                            }
                        }
                    }
                }
            }
        } else {
            for (int index = inclement; index < 0; index++) {
                second--;
                if (second < 0) {
                    second = 59;
                    minute--;
                    if (minute < 0) {
                        minute = 59;
                        hour--;
                        if (hour < 0) {
                            hour = 23;
                            day--;
                            if (day <= 0) {
                                month--;
                                if (month <= 0) {
                                    year--;
                                    if (year <= 0) {
                                        throw new InternalException(Dates.class, "E-UTIL#0036");
                                    } else {
                                        month = 12;
                                        day = DAY_OF_MONTH[11];
                                    }
                                } else {
                                    day = DAY_OF_MONTH[month - 1];
                                    if (!isLeapYear(year) && month == 2) {
                                        day--;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        currentCalendar.set(year, Dates.toCalendarMonth(month), day, hour, minute, second);

        long time = currentCalendar.getTimeInMillis();

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), time);

    }

    /**
     * <ul>
     * ????????.
     * </ul>
     * @param date 
     * @param increment ?
     * @return date ???
     */
    public static Date addMillisecond(Date date, int increment) {

        if (increment == 0) {
            return date;
        }

        long time = date.getTime();
        time = time + increment;

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), time);
    }

    /**
     * <p>
     * ?????????.
     * </p>
     * @param date ??
     * @param type ??????
     * @return ???
     */
    public static Date truncate(Date date, DateType type) {

        Calendar currentCalendar = Dates.getCalendarInstance(date);
        int year = currentCalendar.get(Calendar.YEAR);
        int month = currentCalendar.get(Calendar.MONTH);
        int day = currentCalendar.get(Calendar.DATE);
        int hour = currentCalendar.get(Calendar.HOUR_OF_DAY);
        int minute = currentCalendar.get(Calendar.MINUTE);
        int second = currentCalendar.get(Calendar.SECOND);
        int millis = currentCalendar.get(Calendar.MILLISECOND);

        if (Objects.equals(type, Dates.YEAR)) {
            month = 0;
            day = 1;
            hour = 0;
            minute = 0;
            second = 0;
            millis = 0;
        } else if (Objects.equals(type, Dates.MONTH)) {
            day = 1;
            hour = 0;
            minute = 0;
            second = 0;
            millis = 0;
        } else if (Objects.equals(type, Dates.DAY)) {
            hour = 0;
            minute = 0;
            second = 0;
            millis = 0;
        } else if (Objects.equals(type, Dates.HOUR)) {
            minute = 0;
            second = 0;
            millis = 0;
        } else if (Objects.equals(type, Dates.MINUTE)) {
            second = 0;
            millis = 0;
        } else if (Objects.equals(type, Dates.SECOND)) {
            millis = 0;
        } else if (Objects.equals(type, Dates.MSEC)) {
            /*
             * Timestamp?????? ????????????????????
             */
            if (date instanceof java.sql.Timestamp) {
                // ???
                java.sql.Timestamp timestamp = (java.sql.Timestamp) date;
                millis = timestamp.getNanos() / NANOS_2_MSEC;
            }
        }

        currentCalendar.set(year, month, day, hour, minute, second);
        currentCalendar.set(Calendar.MILLISECOND, millis);

        long afterMillis = currentCalendar.getTimeInMillis();

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), afterMillis);
    }

    /**
     * <p>
     * ??????.
     * </p>
     * @param date ?
     * @return ???
     */
    public static Date endOfMonth(Date date) {

        Calendar currentCalendar = Dates.getCalendarInstance(date);
        int day = DAY_OF_MONTH[currentCalendar.get(Calendar.MONTH)];

        if (!isLeapYear(currentCalendar.get(Calendar.YEAR)) && currentCalendar.get(Calendar.MONTH) == 1) {
            day--;
        }

        currentCalendar.set(currentCalendar.get(Calendar.YEAR), currentCalendar.get(Calendar.MONTH), day,
                currentCalendar.get(Calendar.HOUR_OF_DAY), currentCalendar.get(Calendar.MINUTE),
                currentCalendar.get(Calendar.SECOND));
        currentCalendar.set(Calendar.MILLISECOND, 0);

        long time = currentCalendar.getTimeInMillis();

        /*
         * ???????????? Calendar????????java.util.Date???????
         */
        return instantiateDate(date.getClass(), time);

    }

    /**
     * 2???????????????.
     * @param fromDate1 
     * @param toDate1 
     * @param fromDate2 2
     * @param toDate2 2
     * @return true:??????false:???????
     */
    public static boolean isDateOverlap(Date fromDate1, Date toDate1, Date fromDate2, Date toDate2) {

        fromDate1 = truncate(fromDate1, Dates.DAY);
        toDate1 = truncate(toDate1, Dates.DAY);
        fromDate2 = truncate(fromDate2, Dates.DAY);
        toDate2 = truncate(toDate2, Dates.DAY);
        if ((fromDate1.equals(fromDate2) || toDate1.equals(toDate2) || // ????????
                fromDate1.equals(toDate2) || toDate1.equals(fromDate2))
                || (fromDate1.before(fromDate2) && toDate1.after(fromDate2)) || // ?????????
                (fromDate2.before(fromDate1) && toDate2.after(fromDate1))) // ?????????
            return true;
        return false;
    }

    /**
     * 2?1???????????.
     * @param fromDate1 
     * @param toDate1 
     * @param fromDate2 2
     * @param toDate2 2
     * @return true:?????false:??????
     */
    public static boolean isDateInclude(Date fromDate1, Date toDate1, Date fromDate2, Date toDate2) {

        fromDate1 = truncate(fromDate1, Dates.DAY);
        toDate1 = truncate(toDate1, Dates.DAY);
        fromDate2 = truncate(fromDate2, Dates.DAY);
        toDate2 = truncate(toDate2, Dates.DAY);
        if ((fromDate1.before(fromDate2) || fromDate1.equals(fromDate2)) && // 11??2???
                (toDate1.after(fromDate2) || toDate1.equals(fromDate2))
                && (fromDate1.before(toDate2) || fromDate1.equals(toDate2)) && // ???11??2???
                (toDate1.after(toDate2) || toDate1.equals(toDate2)))
            return true;
        return false;
    }

    /**
     * ?????????.
     * @param year ?
     * @param month ?
     * @param day ?
     * @return ????????????true? ????????false???.
     */
    protected static boolean enableDayOfMonth(int year, int month, int day) {

        int maxDay = DAY_OF_MONTH[month - 1];
        return day <= maxDay && enableLeapYear(year, month, day);
    }

    /**
     * ?????????????.
     * @param year ?
     * @param month ?
     * @param day ?
     * @return ??????????? ??????????true? ????????false???.
     */
    protected static boolean enableLeapYear(int year, int month, int day) {

        if (month == 2) {
            boolean result = Dates.isLeapYear(year);
            if (!result && day == 29) {
                return false;
            } else {
                return true;
            }
        } else {
            return true;
        }
    }

    /**
     * ??????????????????????.<br>
     * ??????????????.
     * @param max ??
     * @param min ???
     * @param values ??
     * @return ???????true?????????false???.
     */
    protected static boolean enableRange(int[] max, int[] min, int[] values) {

        for (int index = 0; index <= values.length - 1; index++) {
            if (values[index] > max[index] || values[index] < min[index]) {
                return false;
            }
        }
        return true;
    }

}

/**
 * <p>
 * .
 * </p>
 * @author ITOCHU Techno-Solutions Corporation
 */
class DateType {

    /**
     * ???.
     */
    private String name;

    /**
     * 
     * @param name ???
     */
    DateType(String name) {

        this.name = name;
    }

    /**
     * {@inheritDoc}
     * @see java.lang.Object#toString()
     */
    public String toString() {

        return this.name;
    }

}