jef.tools.DateUtils.java Source code

Java tutorial

Introduction

Here is the source code for jef.tools.DateUtils.java

Source

/*
 * JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com)
 *
 * 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 jef.tools;

import java.math.BigInteger;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

import jef.common.log.LogUtil;
import jef.tools.support.TimeIterable;

/**
 * utils for date.
 * 
 */
public abstract class DateUtils {
    public static final int SECONDS_IN_DAY = 86400;
    public static final int SECONDS_IN_HOUR = 3600;
    public static final int SECONDS_IN_MINITE = 60;
    public static final int MILLISECONDS_IN_DAY = 86400000;
    public static final int MILLISECONDS_IN_HOUR = 3600000;

    private static String TODAY = "\u4eca\u5929";
    private static String YESTERDAY = "\u6628\u5929";
    private static String TOMORROW = "\u660e\u5929";
    private static String TOMORROW2 = "\u540e\u5929";

    /**
     * ?java.sql.Date
     * 
     * @param d
     * @return
     */
    public static java.sql.Date toSqlDate(Date d) {
        if (d == null)
            return null;
        return new java.sql.Date(d.getTime());
    }

    /**
     * ?SqlTime??
     * 
     * @param date
     * @return
     */
    public static java.sql.Time toSqlTime(Date date) {
        if (date == null)
            return null;
        return new java.sql.Time(date.getTime());
    }

    /**
     * ?java.sql.timestamp
     * 
     * @param d
     * @return
     */
    public static Timestamp toSqlTimeStamp(Date d) {
        if (d == null)
            return null;
        return new java.sql.Timestamp(d.getTime());
    }

    /**
     * java.sql.Date?java.util.Date
     * 
     * @param d
     * @return
     */
    public static Date fromSqlDate(java.sql.Date d) {
        if (d == null)
            return null;
        return new Date(d.getTime());
    }

    /**
     * ???
     * 
     * @param d
     * @return
     */
    public static String formatDate(Date d) {
        if (d == null)
            return "";
        return DateFormats.DATE_CS.get().format(d);
    }

    /**
     * ??????
     * 
     * @param d
     * @return
     */
    public static String formatDateWithToday(Date d) {
        if (d == null)
            return "";
        if (isSameDay(new Date(), d)) {
            return TODAY;
        } else if (isSameDay(futureDay(-1), d)) {
            return YESTERDAY;
        } else if (isSameDay(futureDay(1), d)) {
            return TOMORROW;
        } else if (isSameDay(futureDay(2), d)) {
            return TOMORROW2;
        }
        return DateFormats.DATE_CS.get().format(d);
    }

    /**
     * ?+,????
     * 
     * @param d
     * @return
     */
    public static String formatDateTimeWithToday(Date d) {
        if (d == null)
            return "";
        if (isSameDay(new Date(), d)) {
            return TODAY + " " + DateFormats.TIME_ONLY.get().format(d);
        } else if (isSameDay(yesterday(), d)) {
            return YESTERDAY + " " + DateFormats.TIME_ONLY.get().format(d);
        } else if (isSameDay(futureDay(1), d)) {
            return TOMORROW + " " + DateFormats.TIME_ONLY.get().format(d);
        } else if (isSameDay(futureDay(2), d)) {
            return TOMORROW2 + " " + DateFormats.TIME_ONLY.get().format(d);
        }
        return DateFormats.DATE_TIME_CS.get().format(d);
    }

    /**
     * ?+?
     * 
     * @param d
     * @return
     */
    public static String formatDateTime(Date d) {
        if (d == null)
            return "";
        return DateFormats.DATE_TIME_CS.get().format(d);
    }

    /**
     * dos??Java
     * 
     * @param dostime
     * @return
     */
    public static Date fromDosTime(long dostime) {
        int hiWord = (int) ((dostime & 0xFFFF0000) >>> 16);
        int loWord = (int) (dostime & 0xFFFF);

        Calendar date = Calendar.getInstance();
        int year = ((hiWord & 0xFE00) >>> 9) + 1980;
        int month = (hiWord & 0x01E0) >>> 5;
        int day = hiWord & 0x1F;
        int hour = (loWord & 0xF800) >>> 11;
        int minute = (loWord & 0x07E0) >>> 5;
        int second = (loWord & 0x1F) << 1;
        date.set(year, month - 1, day, hour, minute, second);
        return date.getTime();
    }

    /**
     * ??
     * 
     * @author Administrator
     */
    public static enum TimeUnit {
        DAY(86400000L), HOUR(3600000L), MINUTE(60000L), SECOND(1000L);

        private long ms;

        TimeUnit(long millseconds) {
            this.ms = millseconds;
        }

        public long getMs() {
            return ms;
        }
    }

    /**
     * ??/??
     * 
     * @param d
     *            
     * @param field
     *            ??field. Calendar?
     * @return ?
     */
    public final static void truncate(Date d, int field) {
        d.setTime(org.apache.commons.lang.time.DateUtils.truncate(d, field).getTime());
    }

    /**
     * ??/
     * 
     * @param d
     *            
     * @param field
     *            ??field. Calendar?
     * @return ?
     */
    public final static Date getTruncated(Date d, int field) {
        return org.apache.commons.lang.time.DateUtils.truncate(d, field);
    }

    /**
     * ??/??
     * 
     * @param date
     *            
     * @param field
     *            ??field. Calendar?
     * @return ?
     */
    public final static void truncate(Calendar date, int field) {
        date.setTimeInMillis(org.apache.commons.lang.time.DateUtils.truncate(date, field).getTimeInMillis());
    }

    /**
     * ??/
     * 
     * @param date
     *            
     * @param field
     *            ??field. Calendar?
     * @return ?
     */
    public final static Calendar getTruncated(Calendar date, int field) {
        return org.apache.commons.lang.time.DateUtils.truncate(date, field);
    }

    /**
     * ???? {@link #dayBegin(Date)}?
     * 
     * @param d
     *            
     * @return 
     * @see #dayBegin(Date)
     */
    public final static void truncate(Date d) {
        d.setTime(org.apache.commons.lang.time.DateUtils.truncate(d, Calendar.DATE).getTime());
    }

    /**
     * ???? {@link #dayBegin(Date)}?
     * 
     * @param d
     *            
     * @return 
     * @see #dayBegin(Date)
     */
    public final static Date getTruncated(Date d) {
        return org.apache.commons.lang.time.DateUtils.truncate(d, Calendar.DATE);
    }

    /**
     * ?
     * 
     * @param d
     *            
     * @return 
     * @see #truncate(Date)
     */
    public static Date dayBegin(Date d) {
        return org.apache.commons.lang.time.DateUtils.truncate(d, Calendar.DATE);
    }

    /**
     * ???
     */
    public static Date dayEnd(Date d) {
        d = org.apache.commons.lang.time.DateUtils.truncate(d, Calendar.DATE);
        return new Date(d.getTime() + MILLISECONDS_IN_DAY - 1);
    }

    /**
     *  ??
     * 
     * @param d
     *            
     * @return ?
     */
    public static final Date monthBegin(Date date) {
        return org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.MONTH);
    }

    /**
     * ?
     * 
     * @param date
     * @return ?1
     */
    public static final Date monthEnd(Date date) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));// ?
        calendar = org.apache.commons.lang.time.DateUtils.truncate(calendar, Calendar.DATE);// 
        Date d = calendar.getTime();
        d.setTime(d.getTime() + MILLISECONDS_IN_DAY - 1); // ?1
        return d;
    }

    /**
     * ?
     * 
     * @param date
     * @return ?
     */
    public static final Date lastDayOfMonth(Date date) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));// ?
        calendar = org.apache.commons.lang.time.DateUtils.truncate(calendar, Calendar.DATE);// 
        return calendar.getTime();
    }

    /**
     * ?????
     * 
     * @param d
     * @param unit
     *            ??
     * @param zone
     *            ?? ???
     * @return
     */
    public static boolean isOnTime(Date d, TimeUnit unit, TimeZone zone) {
        BigInteger i = BigInteger.valueOf(d.getTime() + zone.getRawOffset());
        long result = i.mod(BigInteger.valueOf(unit.ms)).longValue();
        return result == 0;
    }

    /**
     * ????? ??
     * 
     * @param d
     * @param unit
     * @return
     */
    public static boolean isOnTime(Date d, TimeUnit unit) {
        return isOnTime(d, unit, TimeZone.getDefault());
    }

    /**
     * ?
     * 
     * @throws
     */
    public static String formatTimeStamp(Date d) {
        if (d == null)
            return "";
        return DateFormats.TIME_STAMP_CS.get().format(d);
    }

    /**
     * ?? ??Format??
     * 
     * @param d
     * @param format
     * @return
     */
    public static String format(Date d, DateFormat format) {
        if (d == null)
            return "";
        synchronized (format) {
            return format.format(d);
        }
    }

    /**
     * ??
     */
    public static String format(Date d, String format) {
        if (d == null)
            return "";
        DateFormat f = new SimpleDateFormat(format);
        return f.format(d);
    }

    /**
     * ?? ThreadLocal?
     * 
     * @param d
     * @param format
     * @return
     */
    public static String format(Date d, ThreadLocal<DateFormat> format) {
        if (d == null)
            return "";
        return format.get().format(d);
    }

    /**
     * ???
     * 
     * @param d
     * @param dateF
     * @param timeF
     * @return
     * @deprecated ??????RSS?
     */
    public static String formatWithToday(Date d, DateFormat dateF, DateFormat timeF) {
        if (d == null)
            return "";
        synchronized (timeF) {
            if (isSameDay(new Date(), d)) {
                return TODAY + " " + timeF.format(d);
            } else if (isSameDay(yesterday(), d)) {
                return YESTERDAY + " " + timeF.format(d);
            } else if (isSameDay(futureDay(1), d)) {
                return TOMORROW + " " + timeF.format(d);
            } else if (isSameDay(futureDay(2), d)) {
                return TOMORROW2 + " " + timeF.format(d);
            } else {
                synchronized (dateF) {
                    return dateF.format(d) + " " + timeF.format(d);
                }
            }
        }
    }

    /**
     * ???
     * 
     * @param s
     * @return
     * @throws ParseException
     */
    public static Date parseDate(String s) throws ParseException {
        if (StringUtils.isBlank(s))
            return null;
        return DateFormats.DATE_CS.get().parse(s);
    }

    /**
     * ???
     * 
     * @param s
     * @return
     * @throws ParseException
     *             ?
     */
    public static Date parseDateTime(String s) throws ParseException {
        if (StringUtils.isBlank(s))
            return null;
        return DateFormats.DATE_TIME_CS.get().parse(s);
    }

    /**
     * ???
     * 
     * @param s
     * @param defaultValue
     * @return
     * @throws ParseException
     *             ??
     */

    public static Date parseDateTime(String s, Date defaultValue) {
        if (StringUtils.isBlank(s))
            return null;
        try {
            return DateFormats.DATE_TIME_CS.get().parse(s);
        } catch (ParseException e) {
            return defaultValue;
        }
    }

    /**
     * ? ?
     * 
     * @param s
     * @param format
     * @return
     * @throws ParseException
     */
    public static Date parse(String s, ThreadLocal<DateFormat> format) throws ParseException {
        if (StringUtils.isBlank(s))
            return null;
        return format.get().parse(s);
    }

    /**
     * ? ?
     * 
     * @Title: parse
     */
    public static Date parse(String s, DateFormat format) throws ParseException {
        if (StringUtils.isBlank(s))
            return null;
        return format.parse(s);
    }

    /**
     * ?()? (??) ?:
     * <ol>
     * <li>?(yyyy-MM-dd)</li>
     * <li>? yyyy-mm-dd</li>
     * <li>?(MM/dd/yyyy)</li>
     * <li>?(MM/dd/yyyy HH:mm:ss)</li>
     * <li>8? (yyyyMMdd)</li>
     * <li>14?(yyyyMMddHHmmss)</li>
     * <li>12?(yyyyMMddHHmm)</li>
     * </ol>
     * 
     * @param dateStr
     * @return ???null
     */
    public static Date autoParse(String dateStr) {
        try {
            int indexOfDash = dateStr.indexOf('-');
            if (indexOfDash > 0) {// ??(??-???)
                if (indexOfDash == 2) {// ???
                    int year = StringUtils.toInt(dateStr.substring(0, indexOfDash), -1);
                    if (year >= 50) {// ???19xx20xx
                        dateStr = "19" + dateStr;
                    } else if (year >= 0) {
                        dateStr = "20" + dateStr;
                    }
                }
                if (dateStr.indexOf(':') > -1) {// 
                    return DateFormats.DATE_TIME_CS.get().parse(dateStr);
                } else {
                    return DateFormats.DATE_CS.get().parse(dateStr);
                }
            } else if (dateStr.indexOf('/') > -1) {// ??
                if (dateStr.indexOf(':') > -1) {// 
                    return DateFormats.DATE_TIME_US.get().parse(dateStr);
                } else {
                    return DateFormats.DATE_US.get().parse(dateStr);
                }
            } else if (dateStr.length() == 8 && StringUtils.isNumeric(dateStr)
                    && (dateStr.startsWith("19") || dateStr.startsWith("20"))) {// 8??
                return DateFormats.DATE_SHORT.get().parse(dateStr);
            } else if (dateStr.length() == 14 && StringUtils.isNumeric(dateStr)
                    && (dateStr.startsWith("19") || dateStr.startsWith("20"))) {// 14??yyyyMMDDHHMMSS
                return DateFormats.DATE_TIME_SHORT_14.get().parse(dateStr);
            } else if (dateStr.length() == 12 && StringUtils.isNumeric(dateStr)
                    && (dateStr.startsWith("19") || dateStr.startsWith("20"))) {// 12??yyyyMMDDHHMM
                return DateFormats.DATE_TIME_SHORT_12.get().parse(dateStr);
            } else if (StringUtils.isNumericOrMinus(dateStr)) {
                long value = Long.valueOf(dateStr).longValue();
                return new Date(value);
            } else {
                return null;
            }
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * ? ??
     * 
     * @return defaultValue ?defaultValue
     * @throws?ParseException
     */
    public static Date parse(String s, DateFormat format, Date defaultValue) {
        if (StringUtils.isBlank(s))
            return defaultValue;
        try {
            return format.parse(s);
        } catch (ParseException e) {
            LogUtil.exception(e);
            return defaultValue;
        }
    }

    /**
     * ? ??
     * 
     * @return defaultValue ?defaultValue
     * @throws?ParseException
     */
    public static Date parse(String s, ThreadLocal<DateFormat> format, Date defaultValue) {
        if (StringUtils.isBlank(s))
            return defaultValue;
        try {
            return format.get().parse(s);
        } catch (ParseException e) {
            LogUtil.exception(e);
            return defaultValue;
        }
    }

    /**
     * ? ??
     * 
     * @return defaultValue ?defaultValue
     * @throws?ParseException
     */
    public static Date parse(String s, String format, Date defaultValue) throws ParseException {
        if (StringUtils.isBlank(s))
            return null;
        try {
            return new SimpleDateFormat(format).parse(s);
        } catch (ParseException e) {
            return defaultValue;
        }
    }

    /**
     * return true if the date 1 and date 2 is on the same day
     * 
     * @param d1
     * @param d2
     * @return
     */
    public static boolean isSameDay(Date d1, Date d2) {
        if (d1 == null && d2 == null)
            return true;
        if (d1 == null || d2 == null)
            return false;
        return org.apache.commons.lang.time.DateUtils.isSameDay(d1, d2);
    }

    /**
     * ??
     * 
     * @param d1
     *            1
     * @param d2
     *            2
     * @return
     */
    public static boolean isSameMonth(Date d1, Date d2) {
        return getTruncated(d1, Calendar.MONTH).getTime() == getTruncated(d2, Calendar.MONTH).getTime();
    }

    /**
     * 
     * 
     * @param d
     * @return
     */
    public static int getYear(Date d) {
        if (d == null)
            return 0;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        return c.get(Calendar.YEAR);
    }

    /**
     *  (1~12)
     * 
     * @param d
     * @return  [1,12]
     */
    public static int getMonth(Date d) {
        if (d == null)
            return 0;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * 
     * 
     * @param d
     * @return
     */
    public static int getDay(Date d) {
        if (d == null)
            return 0;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 
     * 
     * @param d
     * @return 0: ,1~6 
     *         ?Calendarsunday???1?
     *         null-1
     */
    public static int getWeekDay(Date d) {
        if (d == null)
            return -1;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        return c.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * <br>
     *  ?
     * <p>
     * A Week is Sunday ~ Saturday
     * <p>
     * 
     * @param date
     * @return The first day of the week. Note: only the date was adjusted. time
     *         is kept as original.
     */
    public static Date weekBeginUS(Date date) {
        return toWeekDayUS(date, 0);
    }

    /**
     * ?  ??
     * <p>
     * A Week is Sunday ~ Saturday
     * <p>
     * 
     * @param date
     * @return The last day of the week. Note: only the date was adjusted. time
     *         is kept as original.
     */
    public static Date weekEndUS(Date date) {
        return toWeekDayUS(date, 6);
    }

    /**
     * <br>
     *  ?
     * <p>
     * A Week is Monday ~ Sunday
     * <p>
     * 
     * @param date
     * @return The first day of the week. Note: only the date was adjusted. time
     *         is kept as original.
     */
    public static Date weekBegin(Date date) {
        return toWeekDayCS(date, 1);
    }

    /**
     * ?<br>
     *  ??
     * <p>
     * A Week is Monday ~ Sunday
     * <p>
     * 
     * @param date
     * @return The last day of the week. Note: only the date was adjusted. time
     *         is kept as original.
     */
    public static Date weekEnd(Date date) {
        return toWeekDayCS(date, 7);
    }

    private static Date toWeekDayCS(Date date, int expect) {
        int day = getWeekDay(date);
        if (day == 0)
            day = 7;
        return adjustDate(date, 0, 0, expect - day);
    }

    private static Date toWeekDayUS(Date date, int expect) {
        int day = getWeekDay(date);
        return adjustDate(date, 0, 0, expect - day);
    }

    /**
     * ?24?
     * 
     * @param d
     * @return 24??
     */
    public static int getHour(Date d) {
        if (d == null)
            return 0;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 
     * 
     * @param d
     * @return
     */
    public static int getMinute(Date d) {
        if (d == null)
            return 0;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        return c.get(Calendar.MINUTE);
    }

    /**
     * 
     * 
     * @param d
     * @return
     */
    public static int getSecond(Date d) {
        if (d == null)
            return 0;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        return c.get(Calendar.SECOND);
    }

    /**
     * ???
     * 
     * @param d
     * @return int[]{year, month, day}month1~12
     * 
     */
    public static int[] getYMD(Date d) {
        int[] ymd = new int[3];
        if (d == null)
            return ymd;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        ymd[0] = c.get(Calendar.YEAR);
        ymd[1] = c.get(Calendar.MONTH) + 1;
        ymd[2] = c.get(Calendar.DAY_OF_MONTH);
        return ymd;
    }

    /**
     * ??? 
     * 
     * @param d
     * @return
     */
    public static int[] getHMS(Date d) {
        int[] hms = new int[3];
        if (d == null)
            return hms;
        final Calendar c = new GregorianCalendar();
        c.setTime(d);
        hms[0] = c.get(Calendar.HOUR_OF_DAY);
        hms[1] = c.get(Calendar.MINUTE);
        hms[2] = c.get(Calendar.SECOND);
        return hms;
    }

    /**
     * ?1
     * 
     * @throws
     */
    public static void prevMillis(Date d) {
        d.setTime(d.getTime() - 1);
    }

    /**
     * 
     */
    public static void addMillSec(Date d, long value) {
        d.setTime(d.getTime() + value);
    }

    /**
     * 
     */
    public static void addSec(Date d, long value) {
        d.setTime(d.getTime() + value * TimeUnit.SECOND.ms);
    }

    /**
     * 
     */
    public static void addMinute(Date d, int value) {
        d.setTime(d.getTime() + value * TimeUnit.MINUTE.ms);
    }

    /**
     * ?
     */
    public static void addHour(Date d, int value) {
        d.setTime(d.getTime() + value * TimeUnit.HOUR.ms);
    }

    /**
     * 
     */
    public static void addDay(Date d, int value) {
        d.setTime(d.getTime() + value * TimeUnit.DAY.ms);
    }

    /**
     * 
     */
    public static void addMonth(Date d, int value) {
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        c.add(Calendar.MONTH, value);
        d.setTime(c.getTime().getTime());
    }

    /**
     * 
     */
    public static void addYear(Date d, int value) {
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        c.add(Calendar.YEAR, value);
        d.setTime(c.getTime().getTime());
    }

    /**
     * 
     *  ?? ?DateDate
     * 
     * @param date
     *            
     * @param year
     *            ?
     * @param month
     *            ?
     * @param day
     *            ?
     * @return ?
     */
    public static Date adjustDate(Date date, int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, year);
        c.add(Calendar.MONTH, month);
        c.add(Calendar.DAY_OF_YEAR, day);
        return c.getTime();
    }

    /**
     *  ?? ?DateDate
     * 
     * @param date
     *            
     * @param hour
     *            ?
     * @param minute
     *            ?
     * @param second
     *            ?
     * @return ?
     */
    public static Date adjustTime(Date date, int hour, int minute, int second) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR, hour);
        c.add(Calendar.MINUTE, minute);
        c.add(Calendar.SECOND, second);
        return c.getTime();
    }

    /**
     * ?DateDate
     * 
     * @param date
     *            
     * @param mills
     *            ?
     * @return ?
     * 
     */
    public static Date adjust(Date date, long mills) {
        return new Date(date.getTime() + mills);
    }

    /**
     * ?(java.util.Date)
     * 
     * @param year
     *            ?2004
     * @param month
     *            1
     * @param date
     *            1
     * @return ?
     * @deprecated use {@link #get(int, int, int)} instead.
     */
    public static final Date getDate(int year, int month, int date) {
        return get(year, month, date);
    }

    /**
     * ?(java.util.Date)
     * 
     * @param year
     *            ?2004
     * @param month
     *            1
     * @param date
     *            1
     * @return ?
     */
    public static final Date get(int year, int month, int date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, date, 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * ?(java.sql.Date)
     * 
     * @param year
     * @param month
     * @param date
     * @return
     */
    public static final java.sql.Date getSqlDate(int year, int month, int date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, date, 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new java.sql.Date(calendar.getTime().getTime());
    }

    /**
     * ?
     * 
     * @param year
     *            ?2004
     * @param month
     *            1
     * @param date
     *            1
     * @param hour
     *            ?(0-24)
     * @param minute
     *            (0-59)
     * @param second
     *            (0-59)
     * @return Date
     */
    public static final Date get(int year, int month, int date, int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, date, hour, minute, second);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * ?
     * 
     * @param year
     *            ?2004
     * @param month
     *            1
     * @param date
     *            1
     * @param hour
     *            ?(0-24)
     * @param minute
     *            (0-59)
     * @param second
     *            (0-59)
     * @return Date
     * @deprecated Use {@link #get(int, int, int, int, int, int)} instead.
     */
    public static final Date getDate(int year, int month, int date, int hour, int minute, int second) {
        return get(year, month, date, hour, minute, second);
    }

    /**
     * 
     * 
     * @param a
     * @param b
     * @return
     */
    public static final int daySubtract(Date a, Date b) {
        int offset = TimeZone.getDefault().getRawOffset();
        int date = (int) (((a.getTime() + offset) / MILLISECONDS_IN_DAY
                - (b.getTime() + offset) / MILLISECONDS_IN_DAY));
        return date;
    }

    /**
     * 
     * 
     * @param a
     * @param b
     * @return
     */
    public static final long secondSubtract(Date a, Date b) {
        return ((a.getTime() - b.getTime()) / 1000);
    }

    /**
     * ?
     * 
     * @param date
     * @return 22829131
     */
    public static final int getDaysInMonth(Date date) {
        Assert.notNull(date);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        return day;
    }

    /**
     * ?
     * 
     * @param second
     * @return
     */
    public static String formatTimePeriod(long second) {
        return formatTimePeriod(second, null, Locale.getDefault());
    }

    /**
     * ???
     * 
     * @param second
     * @param maxUnit
     *            :?? 0 34? 5
     * @return
     */
    public static String formatTimePeriod(long second, TimeUnit maxUnit, Locale locale) {
        if (locale == null)
            locale = Locale.getDefault();
        if (maxUnit == null) {
            maxUnit = TimeUnit.DAY;
            if (second < SECONDS_IN_DAY)
                maxUnit = TimeUnit.HOUR;
            if (second < SECONDS_IN_HOUR)
                maxUnit = TimeUnit.MINUTE;
            if (second < SECONDS_IN_MINITE)
                maxUnit = TimeUnit.SECOND;
        }
        StringBuilder sb = new StringBuilder();
        if (maxUnit.ms >= TimeUnit.DAY.ms) {
            int days = (int) (second / SECONDS_IN_DAY);
            if (days > 0) {
                sb.append(days);
                if (Locale.US == locale) {
                    sb.append("days ");
                } else {
                    sb.append("");
                }
                second = second - SECONDS_IN_DAY * days;
            }
        }
        if (maxUnit.ms >= TimeUnit.HOUR.ms) {
            int hours = (int) (second / SECONDS_IN_HOUR);
            if (hours > 0) {
                sb.append(hours);
                if (Locale.US == locale) {
                    sb.append("hours ");
                } else {
                    sb.append("?");
                }
                second = second - SECONDS_IN_HOUR * hours;
            }
        }
        if (maxUnit.ms >= TimeUnit.MINUTE.ms) {
            int min = (int) (second / SECONDS_IN_MINITE);
            if (min > 0) {
                sb.append(min);
                if (Locale.US == locale) {
                    sb.append("minutes ");
                } else {
                    sb.append("");
                }
                second = second - SECONDS_IN_MINITE * min;
            }
        }
        if (second > 0) {
            if (Locale.US == locale) {
                sb.append(second).append("seconds");
            } else {
                sb.append(second).append("");
            }
        }
        return sb.toString();
    }

    /**
     * ??
     * 
     * @return
     */
    public static Date yesterday() {
        return futureDay(-1);
    }

    /**
     * ??
     * 
     * @param i
     * @return
     */
    public static Date futureDay(int i) {
        return new Date(System.currentTimeMillis() + (long) MILLISECONDS_IN_DAY * i);
    }

    /**
     * ?()??
     * 
     * @param millseconds
     * @return
     */
    public static String format(long millseconds) {
        Date d = new Date(millseconds);
        return formatDateTime(d);
    }

    /**
     * ?? ????
     * 
     * @param includeStart
     * @param includeEnd
     * @return
     */
    public static Iterable<Date> monthIterator(Date includeStart, Date includeEnd) {
        return new TimeIterable(includeStart, includeEnd, Calendar.MONTH).setIncludeEndDate(true);
    }

    /**
     * ?? ????
     * 
     * @param includeStart
     *            the begin date.(include)
     * @param excludeEnd
     *            the end date(include)
     * @return A Iterable object that can iterate the date.
     */
    public static Iterable<Date> dayIterator(final Date includeStart, final Date includeEnd) {
        return new TimeIterable(includeStart, includeEnd, Calendar.DATE).setIncludeEndDate(true);
    }

    /**
     * 
     * 
     * @return the begin of today.
     */
    public static Date today() {
        return org.apache.commons.lang.time.DateUtils.truncate(new Date(), Calendar.DATE);
    }

    /**
     * 
     * 
     * @return
     */
    public static java.sql.Date sqlToday() {
        return new java.sql.Date(
                org.apache.commons.lang.time.DateUtils.truncate(new Date(), Calendar.DATE).getTime());
    }

    /**
     * 
     * 
     * @return
     */
    public static java.sql.Timestamp sqlNow() {
        return new java.sql.Timestamp(System.currentTimeMillis());
    }

    /**
     * 
     * 
     * @return the current date time.
     */
    public static Date now() {
        return new Date();
    }

    /**
     * ?
     * 
     * @param date
     * @return true if the date is the begin of day.
     */
    public static boolean isDayBegin(Date date) {
        Date d1 = org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DATE);
        return d1.getTime() == date.getTime();
    }

    /**
     * Convert to Instance
     * 
     * @see Instant
     * @param date
     *            java.util.Date
     * @return instant
     */
    public static Instant toInstant(Date date) {
        return date == null ? null : date.toInstant();
    }

    /**
     * Convert LocalDate to jud
     * 
     * @param date
     *            LocalDate
     * @return java.util.Date
     */
    public static Date fromLocalDate(LocalDate date) {
        return date == null ? null : Date.from(date.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * Convert LocalTime to jud.
     * 
     * @param time
     *            LocalTime
     * @return java.util.Date
     */
    public static Date fromLocalTime(LocalTime time) {
        return time == null ? null
                : Date.from(LocalDateTime.of(LocalDate.now(), time).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * Converts LocalDateTime to java.util.Date (null safety)
     * @param LocalDateTime
     * @return java.util.Date
     */
    public static Date fromLocalDateTime(LocalDateTime value) {
        return value == null ? null : Date.from(value.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * Converts java.sql.Date to LocalDate (null safety)
     * @param java.sql.Date
     * @return LocalDate
     */
    public static LocalDate toLocalDate(java.sql.Date date) {
        return date == null ? null : date.toLocalDate();
    }

    /**
     * Converts Time to LocalTime (null safety)
     * @param time
     * @return LocalTime
     */
    public static LocalTime toLocalTime(java.sql.Time time) {
        return time == null ? null : time.toLocalTime();
    }

    /**
     * Converts Timestamp to LocalTime (null safety)
     * @param ts Timestamp
     * @return LocalTime
     */
    public static LocalTime toLocalTime(java.sql.Timestamp ts) {
        return ts == null ? null : ts.toLocalDateTime().toLocalTime();
    }

    /**
     * Converts Timestamp to LocalDateTime (null safety)
     * @param ts Timestamp
     * @return LocalDateTime
     */
    public static LocalDateTime toLocalDateTime(java.sql.Timestamp ts) {
        return ts == null ? null : ts.toLocalDateTime();
    }

    /**
     * Converts LocalDate to Time (null safety)
     * @param date LocalDate
     * @return java.sql.Date
     */
    public static java.sql.Date toSqlDate(LocalDate date) {
        return date == null ? null : java.sql.Date.valueOf(date);
    }

    /**
     * Converts LocalTime to Time (null safety)
     * @param time LocalTime
     * @return java.sql.Time
     */
    public static java.sql.Time toSqlTime(LocalTime time) {
        return time == null ? null : java.sql.Time.valueOf(time);
    }

    /**
     * Converts LocalDateTime to Timestamp (null safety)
     * @param time LocalDateTime
     * @return Timestamp
     */
    public static java.sql.Timestamp toSqlTimeStamp(LocalDateTime time) {
        return time == null ? null : java.sql.Timestamp.valueOf(time);
    }

    /**
     * Converts instant to Timestamp (null safety)
     * @param instant Instant
     * @return java.sql.Timestamp
     */
    public static java.sql.Timestamp toSqlTimeStamp(Instant instant) {
        return instant == null ? null : java.sql.Timestamp.from(instant);
    }

    /**
     * Converts instant to JUD (null safety)
     * @param instant
     * @return java.util.Date
     */
    public static Date fromInstant(Instant instant) {
        return instant == null ? null : Date.from(instant);
    }

    /**
     * Converts LocalTime to Timestamp (null safety)
     * @param localTime LocalTime
     * @return Timestamp
     */
    public static Timestamp toSqlTimeStamp(LocalTime localTime) {
        return localTime == null ? null : java.sql.Timestamp.valueOf(LocalDateTime.of(LocalDate.now(), localTime));
    }
}