我的DateUtils工具类

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

/**
 * Date的通用工具类
 *
 * @author ParanoidCAT
 * @since JDK 1.8
 */
public class DateUtils {
    /**
     * 常量池
     * 由于SimpleDateFormat内部使用了Calendar作为缓存,线程不安全
     * 因此采取的策略是常量池保存pattern字符串,每次都实例化新的SimpleDateFormat
     * 这会导致一定的额外开销,但比起返回错误的字符串或时间显然是值得的
     */
    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
    };

    /**
     * 根据默认格式化模板datePattern将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
     *
     * @param date        待格式化的Date
     * @param datePattern 指定的格式化模板
     * @return java.lang.String
     */
    public static String format(Date date, String datePattern) {
        if (null == date || null == datePattern || datePattern.trim().length() <= 0) {
            return null;
        }
        return new SimpleDateFormat(datePattern).format(date);
    }

    /**
     * 根据指定的解析模板datePattern将String解析为Date
     *
     * @param dateString  待解析的String
     * @param datePattern 指定的解析模板
     * @return java.utils.Date
     */
    public static Date parse(String dateString, String datePattern) {
        try {
            DateFormat dateFormat = new SimpleDateFormat(datePattern);
            Date date = dateFormat.parse(dateString);
            // 注意,这里在完成解析后必须反向格式化进行校验才可以返回
            if (dateString.equals(dateFormat.format(date))) {
                return date;
            } else {
                return null;
            }
        } catch (Exception e) {
            // 没有对入参进行非空校验,所有的异常在这里兜底处理
            return null;
        }
    }

    /**
     * 根据一系列解析模板datePatterns将String解析为Date
     *
     * @param dateString   待解析的String
     * @param datePatterns 一系列解析模板
     * @return java.utils.Date
     */
    public static Date parse(String dateString, String[] datePatterns) {
        if (null == dateString || dateString.trim().length() <= 0 || null == datePatterns) {
            return null;
        }
        Date date = null;
        for (String datePattern : datePatterns) {
            if (null == date) {
                // 重载parse方法的二次封装
                date = parse(dateString, datePattern);
            }
        }
        return date;
    }

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

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

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

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

    /**
     * 变更Date的小时
     *
     * @param date   待变更的Date
     * @param amount 变更的数量(正数为增加负数为减少)
     * @return java.utils.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.utils.Date
     */
    public static Date addMinutes(Date date, Integer amount) {
        return add(date, Calendar.MINUTE, amount);
    }

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

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

    /**
     * 变更Date的时间为0时0分0秒
     *
     * @param date 待变更的Date
     * @return java.utils.Date
     */
    public static Date startTimeOfDate(Date date) {
        if (null == date) {
            return null;
        }
        return parse(format(date, DATE_PATTERN) + " 00:00:00.000", DATE_TIME_MILLISECOND_PATTERN);
    }

    /**
     * 变更Date的时间为23时59分59秒
     *
     * @param date 待变更的Date
     * @return java.utils.Date
     */
    public static Date endTimeOfDate(Date date) {
        if (null == date) {
            return null;
        }
        return parse(format(date, DATE_PATTERN) + " 23:59:59.999", DATE_TIME_MILLISECOND_PATTERN);
    }
}

 

上一篇:csv文件用excel正确的显示日期时间


下一篇:java常见的时间工具类-DateUtils