DateUtils

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Optional;

/**
 * 处理Date的工具类
 * 一方库依赖:无
 * 二方库依赖:无
 * 三方库依赖:无
 *
 * @author ParanoidCAT
 * @since JDK 1.8
 */
public class DateUtils {
    /**
     * 以下是解析或格式化Date时所需的Pattern字符串常量
     * 这些常量字符串将常驻内存中方便在需要的时候作为参数生成SimpleDateFormat
     * 在这里没有使用SimpleDateFormat作为常量的原因是因为其父类DateFormat内部使用了一个Calendar字段来缓存需要处理的Date
     * 由于该字段的修改方法并没有对多线程访问进行限制,因此在并发调用时会导致难以预料的线程安全问题
     * 尽管每次都实例化新的SimpleDateFormat会有一定的额外开销,但比起数据的一致性的确保,这一开销是完全值得的
     *
     * @see DateFormat
     */
    public static final String DATE_PATTERN = "yyyy-MM-dd";
    public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_TIME_MILLISECOND_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String[] PATTERNS = {
            DATE_PATTERN, DATE_TIME_PATTERN, DATE_TIME_MILLISECOND_PATTERN, "yyyy/MM/dd HH:mm:ss"
    };

    /**
     * 根据默认格式化模板将Date格式化为String
     * 默认格式化模板为"yyyy-MM-dd HH:mm:ss"
     *
     * @param date 待格式化的Date
     * @return java.lang.String
     */
    public static String format(Date date) {
        return format(date, DATE_TIME_PATTERN);
    }

    /**
     * 根据指定的格式化模板datePattern将Date格式化为String
     * 若指定的格式化模板为null,使用默认格式化模板
     *
     * @param date        待格式化的Date
     * @param datePattern 指定的格式化模板
     * @return java.lang.String
     */
    public static String format(Date date, String datePattern) {
        try {
            return new SimpleDateFormat(Optional.ofNullable(datePattern).orElse(DATE_TIME_PATTERN)).format(date);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 根据指定的解析模板datePattern将String解析为Date
     *
     * @param dateString  待解析的String
     * @param datePattern 指定的解析模板
     * @return java.util.Date
     */
    public static Date parse(String dateString, String datePattern) {
        try {
            DateFormat dateFormat = new SimpleDateFormat(datePattern);
            Date date = dateFormat.parse(dateString);
            // 注意,这里在完成解析后必须反向格式化进行校验才可以返回
            return dateString.equals(dateFormat.format(date)) ? date : null;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 根据一系列解析模板datePatterns将String解析为Date
     *
     * @param dateString   待解析的String
     * @param datePatterns 一系列解析模板
     * @return java.util.Date
     */
    public static Date parse(String dateString, String[] datePatterns) {
        Date date = null;
        for (String datePattern : Optional.ofNullable(datePatterns).orElse(PATTERNS)) {
            if (null == date) {
                date = parse(dateString, datePattern);
            } else {
                break;
            }
        }
        return date;
    }

    /**
     * 根据默认解析模板将String解析为Date
     *
     * @param dateString 待解析的String
     * @return java.util.Date
     */
    public static Date parse(String dateString) {
        return parse(dateString, PATTERNS);
    }

    /**
     * 对Date进行变更的方法
     * 内部使用Calendar实现
     * 私有方法,只有date和amount为外部传入
     * 为避免amount的形参为int时实参为null自动拆箱即抛出NullPointException(此时未进入方法无法捕获),使用Integer作为形参,在内部处理
     *
     * @param date          待变更的Date
     * @param calendarField Calendar的字段编号
     * @param amount        变更的数量(正数为增加负数为减少)
     * @return java.util.Date
     */
    private static Date add(Date date, int calendarField, Integer amount) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(calendarField, Optional.ofNullable(amount).orElse(0));
            return calendar.getTime();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 变更Date的年
     *
     * @param date   待变更的Date
     * @param amount 变更的数量(正数为增加负数为减少)
     * @return java.util.Date
     */
    public static Date addYears(Date date, Integer amount) {
        return add(date, Calendar.YEAR, amount);
    }

    /**
     * 变更Date的月
     *
     * @param date   待变更的Date
     * @param amount 变更的数量(正数为增加负数为减少)
     * @return java.util.Date
     */
    public static Date addMonths(Date date, Integer amount) {
        return add(date, Calendar.MONTH, amount);
    }

    /**
     * 变更Date的日期
     *
     * @param date   待变更的Date
     * @param amount 变更的数量(正数为增加负数为减少)
     * @return java.util.Date
     */
    public static Date addDays(Date date, Integer amount) {
        return add(date, Calendar.DATE, amount);
    }

    /**
     * 变更Date的小时
     *
     * @param date   待变更的Date
     * @param amount 变更的数量(正数为增加负数为减少)
     * @return java.util.Date
     */
    public static Date addHours(Date date, Integer amount) {
        return add(date, Calendar.HOUR_OF_DAY, amount);
    }

    /**
     * 变更Date的分钟
     *
     * @param date   待变更的Date
     * @param amount 变更的数量(正数为增加负数为减少)
     * @return java.util.Date
     */
    public static Date addMinutes(Date date, Integer amount) {
        return add(date, Calendar.MINUTE, amount);
    }

    /**
     * 变更Date的秒
     *
     * @param date   待变更的Date
     * @param amount 变更的数量(正数为增加负数为减少)
     * @return java.util.Date
     */
    public static Date addSeconds(Date date, Integer amount) {
        return add(date, Calendar.SECOND, amount);
    }

    /**
     * 变更Date的毫秒
     *
     * @param date   待变更的Date
     * @param amount 变更的数量(正数为增加负数为减少)
     * @return java.util.Date
     */
    public static Date addMilliseconds(Date date, Integer amount) {
        return add(date, Calendar.MILLISECOND, amount);
    }

    /**
     * 获取当前日期字符串
     *
     * @return java.lang.String
     */
    public static String getCurrentDate() {
        return format(new Date(), DATE_PATTERN);
    }

    /**
     * 获取当前时间字符串
     *
     * @return java.lang.String
     */
    public static String getCurrentDateTime() {
        return format(new Date(), DATE_TIME_PATTERN);
    }

    /**
     * 获取当前时间(带毫秒)字符串
     *
     * @return java.lang.String
     */
    public static String getCurrentDateTimeMillisecond() {
        return format(new Date(), DATE_TIME_MILLISECOND_PATTERN);
    }

    /**
     * 获取当前小时
     *
     * @return int
     */
    public static int getCurrentHour() {
        return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 变更Date的时间为0时0分0秒
     *
     * @param date 待变更的Date
     * @return java.util.Date
     */
    public static Date getStartOfDate(Date date) {
        try {
            return parse(format(date, DATE_PATTERN) + " 00:00:00", DATE_TIME_PATTERN);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 变更Date的时间为23时59分59秒
     *
     * @param date 待变更的Date
     * @return java.util.Date
     */
    public static Date getEndOfDate(Date date) {
        try {
            return parse(format(date, DATE_PATTERN) + " 23:59:59", DATE_TIME_PATTERN);
        } catch (Exception e) {
            return null;
        }
    }
}

 

posted on 2019-02-02 09:23  纠结的猫  阅读(395)  评论(0)    收藏  举报

导航