JAVA时间转换工具类

import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;

import java.lang.reflect.Field;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author
 * @version 1.0
 * @Description 时间工具类
 * @date 2020/01/08 14:03
 */
public class DateUtils {

    // 缓存
    private static final Map<String, DateTimeFormatter> FORMATTER_CACHE = new ConcurrentHashMap<>();

    private static final String PREFIX = "com.example.project.util.DateUtils$Pattern$";
    private static final String DATE_TIME_CLASS_NAME = "DateTime";
    private static final String DATE_CLASS_NAME = "Date";
    private static final String TIME_CLASS_NAME = "Time";

    private DateUtils() {
    }

    /**
     * 日期的格式化定义
     *
     * @author wangl
     * @date 12/28/2020
     */
    public static class Pattern {
        private Pattern() {
        }

        public static class Date {
            private Date() {
            }

            public static final String YYYY_MM_DD = "yyyy-MM-dd";

            public static final String YYYY_M_DD = "yyyy-M-dd";

            public static final String YYYY_M_D = "yyyy-M-d";

            public static final String YYYY_MM_DD_ = "yyyy/MM/dd";

            public static final String YYYY_M_DD_ = "yyyy/M/dd";

            public static final String YYYY_M_D_ = "yyyy/M/d";

            public static final String YYYYMMDD = "yyyyMMdd";

            public static final String YYYYMDD = "yyyyMdd";

            public static final String YYYYMD = "yyyyMd";

            public static final String MM_DD_YYYY = "MM-dd-yyyy";

            public static final String M_DD_YYYY = "M-dd-yyyy";

            public static final String M_D_YYYY = "M-d-yyyy";

            public static final String MM_DD_YYYY_ = "MM/dd/yyyy";

            public static final String M_DD_YYYY_ = "M/dd/yyyy";

            public static final String M_D_YYYY_ = "M/d/yyyy";

            public static final String MMDDYYYY = "MMddyyyy";

            public static final String MDDYYYY = "Mddyyyy";

            public static final String MDYYYY = "Mdyyyy";
        }

        public static class DateTime {
            private DateTime() {
            }

            public static final String YYYY_MM_DD_SPACE_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

            public static final String YYYY_MM_DD_SPACE_HH_MM = "yyyy-MM-dd HH:mm";

            public static final String YYYY_M_D_SPACE_H_M_S = "yyyy-M-d H:m:s";

            public static final String YYYY_MM_DD_SPACE_HH_MM_SS_ = "yyyy/MM/dd HH:mm:ss";

            public static final String HH_MM_SPACE_YYYY_MM_DD = "HH:mm yyyy-MM-dd";

            public static final String HH_MM_SPACE_YYYY_MM_DD_ = "HH:mm yyyy/MM/dd";

            public static final String H_MM_SPACE_YYYY_MM_DD = "H:mm yyyy-MM-dd";

            public static final String H_MM_SPACE_YYYY_MM_DD_ = "H:mm yyyy/MM/dd";

            public static final String H_MM_COMMA_YYYY_MM_DD = "H:mm,yyyy-MM-dd";

            public static final String H_MM_COMMA_YYYY_MM_DD_ = "H:mm,yyyy/MM/dd";

            public static final String H_MM_COMMA_YYYY_M_D = "H:mm,yyyy-M-d";

            public static final String H_M_COMMA_YYYY_M_D = "H:m,yyyy-M-d";

            public static final String H_MM_COMMA_YYYY_M_D_ = "H:mm,yyyy/M/d";

            public static final String H_M_COMMA_YYYY_M_D_ = "H:m,yyyy/M/d";

            public static final String YYYY_MM_DD_HH_MM = "yyyyMMddHHmm";

            public static final String YYYY_MM_DD_HH_MM_SS = "yyyyMMddHHmmss";
        }

        public static class Time {
            private Time() {
            }

            public static final String HH_MM_SS = "HH:mm:ss";

            public static final String H_M_S = "H:m:s";

            public static final String HH_MM = "HH:mm";

            public static final String H_MM = "H:mm";

            public static final String H_M = "H:m";

            public static final String HH = "HH";

            public static final String HHMM = "HHmm";

            public static final String HHMMSS = "HHmmss";
        }
    }

    /**
     * Date --> LocalDateTime
     *
     * @param date
     * @return LocalDateTime
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        // 获取系统默认时区
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * @return Date
     * @Description LocalDateTime  ->  Date
     * @Param localDateTime
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = localDateTime.atZone(zone);
        Instant instant = zonedDateTime.toInstant();
        return Date.from(instant);
    }

    /**
     * Date --> String
     *
     * @param time    时分秒
     * @param pattern 时间格式(静态内部类实现)
     * @return
     */
    public static String formatTime(@NonNull Date time, @NonNull String pattern) {
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        Instant instant = time.toInstant();
        // 获取系统默认时区
        ZoneId zone = ZoneId.systemDefault();
        LocalTime formatTime = LocalDateTime.ofInstant(instant, zone).toLocalTime();
        return formatLocalTime(formatTime, pattern);
    }

    /**
     * Date --> String
     *
     * @param date    年月日
     * @param pattern 日期格式(静态内部类实现)
     * @return
     */
    public static String formatDate(@NonNull Date date, @NonNull String pattern) {
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        Instant instant = date.toInstant();
        // 获取系统默认时区
        ZoneId zone = ZoneId.systemDefault();
        LocalDate localDate = LocalDateTime.ofInstant(instant, zone).toLocalDate();
        return formatLocalDate(localDate, pattern);
    }


    /**
     * Date --> String
     *
     * @param dateTime 年月日时分秒
     * @param pattern  日期格式(静态内部类实现)
     * @return
     */
    public static String formatDateTime(@NonNull Date dateTime, @NonNull String pattern) {
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        Instant instant = dateTime.toInstant();
        // 获取系统默认时区
        ZoneId zone = ZoneId.systemDefault();
        LocalDateTime formatDateTime = LocalDateTime.ofInstant(instant, zone);
        return formatLocalDateTime(formatDateTime, pattern);
    }


    /**
     * LocalDate(时分秒) --> String
     *
     * @param localTime
     * @param pattern   时间格式(静态内部类实现)
     * @return
     */
    public static String formatLocalTime(@NonNull LocalTime localTime, @NonNull String pattern) {
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return localTime.format(formatter);
    }

    /**
     * LocalDate(年月日) --> String
     *
     * @param localDate
     * @param pattern   日期格式(静态内部类实现)
     * @return
     */
    public static String formatLocalDate(@NonNull LocalDate localDate, @NonNull String pattern) {
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return localDate.format(formatter);
    }


    /**
     * LocalDateTime(年月日时分秒) --> String
     *
     * @param localDateTime
     * @param pattern       日期格式(静态内部类实现)
     * @return
     */
    public static String formatLocalDateTime(@NonNull LocalDateTime localDateTime, @NonNull String pattern) {
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return localDateTime.format(formatter);
    }


    /**
     * String(年月日) --> Date
     *
     * @param date
     * @param pattern 日期格式(静态内部类实现)
     * @return
     */
    public static Date parseDate(@NonNull String date, @NonNull String pattern) {
        LocalDate localDate = stringToLocalDate(date, pattern);
        Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    /**
     * String(年月日时分秒) --> Date
     *
     * @param dateTime
     * @param pattern  日期格式(静态内部类实现)
     * @return
     */
    public static Date parseDateTime(@NonNull String dateTime, @NonNull String pattern) {
        if (StringUtils.isBlank(dateTime)) {
            throw new NullPointerException("date is null");
        }
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        LocalDateTime localDateTime = parseLocalDateTime(dateTime, pattern);
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    /**
     * String(年月日) --> LocalTime
     *
     * @param time
     * @param pattern 日期格式(静态内部类实现)
     * @return parseLocalTime
     */
    public static LocalTime stringToLocalTime(@NonNull String time, @NonNull String pattern) {
        if (StringUtils.isBlank(time)) {
            throw new NullPointerException("time is null");
        }
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return LocalTime.parse(time, formatter);
    }


    /**
     * String(年月日) --> LocalDate
     *
     * @param date
     * @param pattern 日期格式(静态内部类实现)
     * @return
     */
    private static LocalDate stringToLocalDate(@NonNull String date, @NonNull String pattern) {
        if (StringUtils.isBlank(date)) {
            throw new NullPointerException("date is null");
        }
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return LocalDate.parse(date, formatter);
    }

    /**
     * String(年月日时分秒) --> LocalDateTime
     *
     * @param dateTime
     * @param pattern  日期格式(静态内部类实现)
     * @return
     */
    private static LocalDateTime stringToLocalDateTime(@NonNull String dateTime, @NonNull String pattern) {
        if (StringUtils.isBlank(dateTime)) {
            throw new NullPointerException("date is null");
        }
        if (StringUtils.isBlank(pattern)) {
            throw new NullPointerException("pattern is null");
        }
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return LocalDateTime.parse(dateTime, formatter);
    }

    /**
     * @return
     * @Description 适配字符串转 LocalDate
     *
     * <pre>
     *  只有时间时,会补全日期为1970-01-01
     * </pre>
     * @Param [date, format]
     */
    public static LocalDate parseLocalDate(@NonNull String date, @NonNull String format) {
        if (StringUtils.isBlank(date)) {
            throw new NullPointerException("date is null");
        }
        if (StringUtils.isBlank(format)) {
            throw new NullPointerException("format is null");
        }
        LocalDate localDate;
        try {
            if (containsContent(format, PREFIX + DATE_TIME_CLASS_NAME)) {
                localDate = stringToLocalDateTime(date, format).toLocalDate();
            } else if (containsContent(format, PREFIX + DATE_CLASS_NAME)) {
                localDate = stringToLocalDate(date, format);
            } else if (containsContent(format, PREFIX + TIME_CLASS_NAME)) {
                localDate = LocalDate.of(1970, 1, 1);
            } else {
                throw new RuntimeException("不支持的时间类型");
            }
            return localDate;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @return
     * @Description 适配字符串转 LocalDateTime
     *
     * <pre>
     *  只有日期时,会不全时间为00:00:00
     *  只有时间时,会补全日期为1970-01-01
     * </pre>
     * @Param [date, format]
     */
    public static LocalDateTime parseLocalDateTime(@NonNull String date, @NonNull String format) {
        if (StringUtils.isBlank(date)) {
            throw new NullPointerException("date is null");
        }
        if (StringUtils.isBlank(format)) {
            throw new NullPointerException("format is null");
        }
        LocalDateTime localDateTime;
        try {
            if (containsContent(format, PREFIX + DATE_TIME_CLASS_NAME)) {
                localDateTime = stringToLocalDateTime(date, format);
            } else if (containsContent(format, PREFIX + DATE_CLASS_NAME)) {
                LocalDate localDate = stringToLocalDate(date, format);
                // 指定时间形成新日期时间
                localDateTime = localDate.atTime(0, 0, 0);
            } else if (containsContent(format, PREFIX + TIME_CLASS_NAME)) {
                LocalDate localDate = LocalDate.of(1970, 1, 1);
                LocalTime localTime = stringToLocalTime(date, format);
                localDateTime = localTime.atDate(localDate);
            } else {
                throw new RuntimeException("不支持的时间类型");
            }
            return localDateTime;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @return long 时间戳(毫秒)
     * @Description localDateTime -> long
     * @Param localDateTime
     */
    public static long parseTimestamp(@NonNull LocalDateTime localDateTime) {
        return localDateTime.toInstant(localDateTime.atZone(ZoneId.systemDefault()).getOffset()).toEpochMilli();
    }

    /**
     * @return long 时间戳(毫秒)
     * @Description String -> long
     * @Param date
     * @Param format
     */
    public static long parseTimestamp(@NonNull String date, @NonNull String format) {
        return parseTimestamp(parseLocalDateTime(date, format));
    }

    /**
     * @return long 时间戳(毫秒)
     * @Description Date -> long
     * @Param date
     */
    public static long parseTimestamp(@NonNull Date date) {
        return parseTimestamp(dateToLocalDateTime(date));
    }

    /**
     * @param begin 开始日期
     * @param end   结束日期
     * @return 调用period的get方法可获取年月日日期差
     * @Description TODO 计算日期差
     */
    public static Period calculationPeriod(@NonNull Date begin, @NonNull Date end) {
        LocalDate beginLocalDate = dateToLocalDateTime(begin).toLocalDate();
        LocalDate endLocalDate = dateToLocalDateTime(end).toLocalDate();
        return Period.between(beginLocalDate, endLocalDate);
    }

    /**
     * @return 调用period的get方法可获取年月日日期差
     * @Description TODO 计算日期差
     * @Param begin 开始时间
     * @Param end 结束时间
     * @format 时间格式(必须和传入的开始和结束时间格式一致)
     */
    public static Period calculationPeriod(@NonNull String begin, @NonNull String end, @NonNull String format) {
        if (StringUtils.isBlank(begin) || StringUtils.isBlank(end)) {
            throw new NullPointerException("date is null");
        }
        if (StringUtils.isBlank(format)) {
            throw new NullPointerException("pattern is null");
        }
        LocalDate beginLocalDate = parseLocalDateTime(begin, format).toLocalDate();
        LocalDate endLocalDate = parseLocalDateTime(end, format).toLocalDate();
        return Period.between(beginLocalDate, endLocalDate);
    }


    /**
     * @return 调用duration的to方法可获取时分秒时间差
     * @Description TODO 计算时间差
     * @Param begin 开始时间
     * @Param end 结束时间
     * @format 时间格式(必须和传入的开始和结束时间格式一致)
     * 1990-01-01 13:20:56
     */
    public static Duration calculationDuration(@NonNull String begin, @NonNull String end, @NonNull String format) {
        if (StringUtils.isBlank(begin) || StringUtils.isBlank(end)) {
            throw new NullPointerException("date is null");
        }
        if (StringUtils.isBlank(format)) {
            throw new NullPointerException("pattern is null");
        }
        LocalDateTime beginLocalDateTime = parseLocalDateTime(begin, format);
        LocalDateTime endLocalDateTime = parseLocalDateTime(end, format);
        return Duration.between(beginLocalDateTime, endLocalDateTime);
    }

    /**
     * @return 时分秒
     * @Description TODO 计算时间差
     * @Param begin 开始时间
     * @Param end 结束时间
     * 1990-01-01 13:20:56
     */
    public static Duration calculationDuration(@NonNull Date begin, @NonNull Date end) {
        LocalDateTime beginLocalDateTime = dateToLocalDateTime(begin);
        LocalDateTime endLocalDateTime = dateToLocalDateTime(end);
        return Duration.between(beginLocalDateTime, endLocalDateTime);
    }

    /**
     * 日期的加减(仅支持天/小时/分/秒)
     *
     * @param date     基础时间
     * @param addValue 增量(负数则日期减少)
     * @param unit     时间单位
     * @return
     */
    public static Date dateAdd(@NonNull Date date, int addValue, TimeUnit unit) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        if (TimeUnit.DAYS.equals(unit)) {
            cal.add(Calendar.DAY_OF_YEAR, addValue);
        } else if (TimeUnit.HOURS.equals(unit)) {
            cal.add(Calendar.HOUR_OF_DAY, addValue);
        } else if (TimeUnit.MINUTES.equals(unit)) {
            cal.add(Calendar.MINUTE, addValue);
        } else if (TimeUnit.SECONDS.equals(unit)) {
            cal.add(Calendar.SECOND, addValue);
        } else {
            throw new RuntimeException("Time type not supported");
        }
        return cal.getTime();
    }

    /**
     * DateTimeFormatter缓存
     *
     * @param
     * @param
     * @return
     */
    private static DateTimeFormatter createCacheFormatter(String pattern) {
        if (pattern == null || pattern.length() == 0) {
            throw new IllegalArgumentException("Invalid pattern specification");
        }
        // 先从缓存中获取DateTimeFormatter,有就返回。没有再创建
        DateTimeFormatter formatter = FORMATTER_CACHE.get(pattern);
        if (null == formatter) {
            formatter = DateTimeFormatter.ofPattern(pattern);
            FORMATTER_CACHE.put(pattern, formatter);
        }
        return formatter;
    }

    /**
     * @return
     * @Description 查看格式是否在内部类常量中
     * @Param [format, className]
     */
    private static boolean containsContent(String format, String className) throws ClassNotFoundException, IllegalAccessException {
        Class<?> clazz = Class.forName(className);
        Field[] fields = clazz.getDeclaredFields();
        if (!(fields.length > 0)) {
            return false;
        }
        for (Field field : fields) {
            String fieldName = field.getName();
            String fieldValue = (String) field.get(fieldName);
            if (format.equals(fieldValue)) {
                return true;
            }
        }
        return false;
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值