日期时间实战

日期时间各种转换,以LocalDateTime为中介。

DateUtils

重构后的代码

package com.nightglow.util;

import java.sql.Timestamp;
import java.time.DateTimeException;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;

public class DateUtils {

    public static final String YYYYMMDD_PATTERN = "yyyyMMdd";
    public static final String YYYY_MMDD_PATTERN = "yyyy-MM-dd";
    public static final String YYYYMMDDHHMMSS_PATTERN = "yyyyMMddHHmmss";
    public static final String YYYY_MM_DD_HH_MM_SS_PATTERN = "yyyy-MM-dd HH:mm:ss";

    private static final ZoneOffset CHINA_ZONE = ZoneOffset.of("+8");

    public static LocalDateTime mills2DateTime(Long mills) {
        if (Objects.isNull(mills)) {
            return null;
        }

        try {
            Instant instant = Instant.ofEpochMilli(mills);
            return LocalDateTime.ofInstant(instant, CHINA_ZONE);
        } catch (DateTimeException e) {
            // log
        }
        return null;
    }

    public static Long dateTime2Mills(LocalDateTime dateTime) {
        if (Objects.isNull(dateTime)) {
            return null;
        }

        try {
            return dateTime.toInstant(CHINA_ZONE).toEpochMilli();
        } catch (ArithmeticException e) {
            // log
        }
        return null;
    }

    public static LocalDateTime str2DateTime(String str) {
        return str2DateTime(str, YYYY_MM_DD_HH_MM_SS_PATTERN);
    }

    public static LocalDateTime str2DateTime(String str, String pattern) {
        if (StringUtils.isBlank(str) || StringUtils.isBlank(pattern)) {
            return null;
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        try {
            return LocalDateTime.parse(str, formatter);
        } catch (DateTimeParseException e) {
            // log
        }
        return null;
    }

    public static String dateTime2Str(LocalDateTime dateTime) {
        return dateTime2Str(dateTime, YYYY_MM_DD_HH_MM_SS_PATTERN);
    }

    public static String dateTime2Str(LocalDateTime dateTime, String pattern) {
        if (Objects.isNull(dateTime) || StringUtils.isBlank(pattern)) {
            return null;
        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        try {
            return dateTime.format(formatter);
        } catch (DateTimeException e) {
            // log
        }
        return null;
    }

    public static LocalDateTime timeStamp2DateTime(Timestamp timestamp) {
        if (Objects.isNull(timestamp)) {
            return null;
        }

        return timestamp.toLocalDateTime();
    }

    public static Timestamp dateTime2TimeStamp(LocalDateTime dateTime) {
        if (Objects.isNull(dateTime)) {
            return null;
        }

        return Timestamp.valueOf(dateTime);
    }

    public static LocalDateTime date2DateTime(Date date) {
        if (Objects.isNull(date)) {
            return null;
        }

        try {
            return LocalDateTime.ofInstant(date.toInstant(), CHINA_ZONE);
        } catch (DateTimeException e) {
            // log
        }
        return null;
    }

    public static Long nanosBetween(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        if (Objects.isNull(startDateTime) || Objects.isNull(endDateTime)) {
            return null;
        }

        Duration duration = Duration.between(startDateTime, endDateTime);
        return duration.toNanos();
    }

    /*
     * plus负值,等价minus
     */
    public static LocalDateTime plusTime(LocalDateTime dateTime, Long value, ChronoUnit chronoUnit) {
        if (Objects.isNull(dateTime) || Objects.isNull(value) || Objects.isNull(chronoUnit)) {
            return null;
        }

        return dateTime.plus(value, chronoUnit);
    }

    public static Long convertByTimeUnit(Long srcValue, TimeUnit srcTimeUnit, TimeUnit timeUnit) {
        if (Objects.isNull(srcValue) || Objects.isNull(srcTimeUnit) || Objects.isNull(timeUnit)) {
            return null;
        }

        return timeUnit.convert(srcValue, srcTimeUnit);
    }
}

场景验证

用DateUtils中静态方法替换老的DateUtil,验证其通用性;
实际开发中需判null或者使用Optional。

DateUtil验证代码

package com.nightglow.util;

import com.google.common.collect.Maps;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.nightglow.util.DateUtils.YYYYMMDD_PATTERN;
import static com.nightglow.util.DateUtils.YYYY_MMDD_PATTERN;
import static com.nightglow.util.DateUtils.YYYY_MM_DD_HH_MM_SS_PATTERN;

public class DateUtil {
    public static final int DAY_MINUTES = 24 * 60;

    public static void cmp1() {
        System.out.println(DAY_MINUTES);

        System.out.println(DateUtils.convertByTimeUnit(1L, TimeUnit.DAYS, TimeUnit.MINUTES));
    }


    public static String parseDateMinusDays(LocalDate localDate, int day, String format) {
        LocalDate date = localDate.minusDays(day);
        String str = date.format(DateTimeFormatter.ofPattern(format));
        return str;
    }

    public static void cmp2() {
        LocalDate localDate = LocalDate.now();
        int day = 1;
        String format = DateUtils.YYYY_MMDD_PATTERN;

        System.out.println(parseDateMinusDays(localDate, day, format));

        LocalDateTime dateTime = localDate.atTime(LocalTime.now());
        LocalDateTime minuteDateTime = DateUtils.plusTime(dateTime, Long.valueOf(-day), ChronoUnit.DAYS);
        System.out.println(DateUtils.dateTime2Str(minuteDateTime, format));
    }


    public static String getLocalDateStr(LocalDate localDate) {
        if (Objects.isNull(localDate)) {
            return null;
        }
        return localDate.format(DateTimeFormatter.ofPattern(YYYY_MMDD_PATTERN));
    }

    public static void cmp3() {
        LocalDate localDate = LocalDate.now();

        System.out.println(getLocalDateStr(localDate));

        LocalDateTime dateTime = localDate.atTime(LocalTime.now());
        System.out.println(DateUtils.dateTime2Str(dateTime, YYYY_MMDD_PATTERN));
    }


    public static LocalDate getNeighboringLocalDate(int relativeDays) {
        LocalDate today = LocalDate.now();
        return today.plusDays(relativeDays);
    }

    public static void cmp4() {
        int relativeDays = 1;

        System.out.println(getNeighboringLocalDate(relativeDays));

        LocalDateTime dateTime = DateUtils.plusTime(LocalDateTime.now(), Long.valueOf(relativeDays), ChronoUnit.DAYS);
        System.out.println(dateTime.toLocalDate());

    }

    /**
     * 时间相差的分钟数
     * @param startTime
     * @param endTime
     * @return
     */
    public static long localDateTimeDiff2Minutes(LocalDateTime startTime, LocalDateTime endTime){
        Duration duration = Duration.between(startTime ,endTime);
        return duration.toMinutes();
    }

    public static void cmp5() {
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusDays(1);

        System.out.println(localDateTimeDiff2Minutes(startTime, endTime));

        Long nanos = DateUtils.nanosBetween(startTime, endTime);
        System.out.println(DateUtils.convertByTimeUnit(nanos, TimeUnit.NANOSECONDS, TimeUnit.MINUTES));

    }


    /**
     * 获取今天的指定时间
     *
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    public static LocalDateTime getTodayLocalDateTime(int hour, int minute, int second) {
        LocalDateTime now = LocalDateTime.now();
        return LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), hour, minute, second);
    }

    public static void cmp6() {
        int hour = 12;
        int minute = 0;
        int second = 0;

        System.out.println(getTodayLocalDateTime(hour, minute, second));

        System.out.println(LocalDateTime.of(LocalDate.now(), LocalTime.of(hour, minute, second)));
    }


    /**
     * 日期格式化
     * @param date
     * @param pattern
     * @return
     */
    public static String date2Str(Date date, String pattern){
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    public static void cmp7() {
        Date date = new Date();
        String pattern = DateUtils.YYYY_MM_DD_HH_MM_SS_PATTERN;

        System.out.println(date2Str(date, pattern));

        LocalDateTime dateTime = DateUtils.date2DateTime(date);
        System.out.println(DateUtils.dateTime2Str(dateTime, pattern));
    }


    /**
     * Date类型转为Timestamp类型
     *
     * @param date
     * @return Timestamp
     */
    public static Timestamp dateToTimestamp(Date date) {
        return new Timestamp(date.getTime());
    }

    public static void cmp8() {
        Date date = new Date();

        System.out.println(dateToTimestamp(date));

        LocalDateTime dateTime = DateUtils.date2DateTime(date);
        System.out.println(DateUtils.dateTime2TimeStamp(dateTime));
    }


    /**
     * 获取某天所在的日期,例如20220106
     *
     * @param day 0 表示当前日期,往前的天数(负数),往后的天数(正数)
     * @return
     */
    public static String constructDate(int day) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(YYYYMMDD_PATTERN);
        LocalDate targetDate = LocalDate.now().plus(day, ChronoUnit.DAYS);
        return dateFormatter.format(targetDate);
    }

    public static void cmp9() {
        int day = 1;

        System.out.println(constructDate(day));

        LocalDateTime dateTime = DateUtils.plusTime(LocalDateTime.now(), Long.valueOf(day), ChronoUnit.DAYS);
        System.out.println(DateUtils.dateTime2Str(dateTime, YYYYMMDD_PATTERN));
    }


    /**
     * 获取某天所在月的第一天
     *
     * @param day 0 表示当前日期,往前的天数(负数),往后的天数(正数)
     * @return
     */
    public static String constructFirstDayOfMonth(int day) {
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(YYYYMMDD_PATTERN);
        LocalDate targetDate = LocalDate.now().plus(day, ChronoUnit.DAYS);
        targetDate = targetDate.with(TemporalAdjusters.firstDayOfMonth());
        return dateFormatter.format(targetDate);
    }

    public static void cmp10() {
        int day = 10;

        System.out.println(constructFirstDayOfMonth(day));

        LocalDateTime dateTime = DateUtils.plusTime(LocalDateTime.now(), Long.valueOf(day), ChronoUnit.DAYS);
        LocalDateTime adjustDateTime = dateTime.with(TemporalAdjusters.firstDayOfMonth());
        System.out.println(DateUtils.dateTime2Str(adjustDateTime, YYYYMMDD_PATTERN));
    }

    /**
     * 获取某一天前一天的起始和结束时间
     * @param day day 0 表示当前日期,往前的天数(负数),往后的天数(正数)
     * @param pattern 格式化 yyyy-MM-dd HH:mm:ss:SSS
     * @return
     */
    public static Map<String, Object> constructStartAndEndTimeOfDay (int day, String pattern) {
        Map<String, Object> mapTime = Maps.newHashMap();

        Calendar cal = Calendar.getInstance();

        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DAY_OF_MONTH, day);
        Date startOfPreviousDay = cal.getTime();

        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 999);
        Date endOfPreviousDay = cal.getTime();
        //格式转换
        //前一天凌晨时间 2022-12-11 00:00:00.000
        String startTime = date2Str(startOfPreviousDay,pattern);
        //前一天末尾时间 2022-12-11 23:59:59.999
        String endTime = date2Str(endOfPreviousDay,pattern);
        mapTime.put("startTime",startTime);
        mapTime.put("endTime",endTime);
        return mapTime;
    }

    public static void cmp11() {
        int day = 1;
        String pattern = YYYY_MM_DD_HH_MM_SS_PATTERN;

        System.out.println(constructStartAndEndTimeOfDay(day, pattern));


        LocalDateTime dateTime = LocalDateTime.now();
        LocalDateTime adjustDateTime = DateUtils.plusTime(dateTime, Long.valueOf(day), ChronoUnit.DAYS);

        Map<String, String> result = Maps.newHashMap();
        LocalDateTime startDateTime = LocalDateTime.of(adjustDateTime.toLocalDate(), LocalTime.MIN);
        LocalDateTime endDateTime = LocalDateTime.of(adjustDateTime.toLocalDate(), LocalTime.MAX);
        result.put("startTime", DateUtils.dateTime2Str(startDateTime, pattern));
        result.put("endTime", DateUtils.dateTime2Str(endDateTime, pattern));
        System.out.println(result);
    }

    /**
     * 计算两个时间相距多少秒
     *
     * @param before
     * @return
     */
    public static int secondsBetween(Date before, Date after) {
        return (int) ((after.getTime() - before.getTime()) / 1000);
    }

    public static void cmp12() {
        Date before = new Date();
        Date after = new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(1));

        System.out.println(secondsBetween(before, after));

        LocalDateTime startDateTime = DateUtils.date2DateTime(before);
        LocalDateTime endDateTime = DateUtils.date2DateTime(after);
        Long nanos = DateUtils.nanosBetween(startDateTime, endDateTime);
        System.out.println(DateUtils.convertByTimeUnit(nanos, TimeUnit.NANOSECONDS, TimeUnit.SECONDS));
    }

    /**
     * 计算两个时间相距多少分钟
     *
     * @param before
     * @return
     */
    public static int minutesBetween(Date before, Date after) {
        try {
            return (int) ((after.getTime() - before.getTime()) / 1000 / 60);
        } catch (Exception e) {
            return 0;
        }
    }

    public static void cmp13() {
        Date before = new Date();
        Date after = new Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(10));

        System.out.println(minutesBetween(before, after));

        LocalDateTime startDateTime = DateUtils.date2DateTime(before);
        LocalDateTime endDateTime = DateUtils.date2DateTime(after);
        Long nanos = DateUtils.nanosBetween(startDateTime, endDateTime);
        System.out.println(DateUtils.convertByTimeUnit(nanos, TimeUnit.NANOSECONDS, TimeUnit.MINUTES));
    }


    /**
     * 计算 minute 分钟后的时间
     *
     * @param date
     * @param minute
     * @return
     */
    public static Date addMinute(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    public static void cmp14() {
        Date date = new Date();
        int minute = 1;

        System.out.println(addMinute(date, minute));

        LocalDateTime dateTime = DateUtils.date2DateTime(date);
        LocalDateTime adjustDateTime = DateUtils.plusTime(dateTime, Long.valueOf(minute), ChronoUnit.MINUTES);
        System.out.println(DateUtils.dateTime2Date(adjustDateTime));
    }

    /**
     * 计算 minute 分钟前的时间
     *
     * @param date
     * @param minute
     * @return
     */
    public static Date delMinute(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar. add(Calendar.MINUTE, -minute);
        return calendar.getTime();
    }

    public static void cmp15() {
        Date date = new Date();
        int minute = 10;

        System.out.println(delMinute(date, minute));

        LocalDateTime dateTime = DateUtils.date2DateTime(date);
        LocalDateTime adjustDateTime = DateUtils.plusTime(dateTime, Long.valueOf(-minute), ChronoUnit.MINUTES);
        System.out.println(DateUtils.dateTime2Date(adjustDateTime));
    }

    /**
     * 将yyyy-MM-dd HH:mm:ss或者yyyy-MM-dd'T'HH:mm:ss 或其他格式转换为Date类型
     */
    public static Date dateStr2Date(String dateStr, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            // log
        }
        return null;
    }

    public static void cmp16() {
        String dateStr = "2023-07-01 00:00:00";
        String pattern = YYYY_MM_DD_HH_MM_SS_PATTERN;

        System.out.println(dateStr2Date(dateStr, pattern));

        LocalDateTime dateTime = DateUtils.str2DateTime(dateStr, pattern);
        System.out.println(DateUtils.dateTime2Date(dateTime));
    }

    /**
     * 针对业务上传的特殊日期格式转换
     * eg:2023/5/31 09:43 -> 2023-05-31 09:43:00
     */
    public static String specialDateStr2Str(String dateStr) {
        String str = "";
        try {
            if (dateStr.contains("/")) {
                str = date2Str(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(dateStr.length() <= 16 ? dateStr.concat(":00") : dateStr), "yyyy-MM-dd HH:mm:ss");
            } else if (dateStr.contains("-")) {
                str = date2Str(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr.length() <= 16 ? dateStr.concat(":00") : dateStr), "yyyy-MM-dd HH:mm:ss");
            }
        } catch (Exception e) {
            // log
        }
        return str;
    }

    public static void cmp17() {
        String dateStr = "2023-07-01 00:00";
        System.out.println(specialDateStr2Str(dateStr));

        LocalDateTime dateTime = DateUtils.str2DateTime(dateStr, "[yyyy/MM/dd HH:mm:ss][yyyy/MM/dd HH:mm][yyyy-MM-dd HH:mm:ss][yyyy-MM-dd HH:mm]");
        System.out.println(DateUtils.dateTime2Str(dateTime, "yyyy-MM-dd HH:mm:ss"));

    }

    public static void main(String[] args) {
        cmp1();

        cmp2();

        cmp3();

        cmp4();

        cmp5();

        cmp6();

        cmp7();

        cmp8();

        cmp9();

        cmp10();

        cmp11();

        cmp12();

        cmp13();

        cmp14();

        cmp15();

        cmp16();

        cmp17();
    }

}

引用

  1. 高度有用的Java ChronoUnit枚举
posted @ 2023-06-30 01:26  蒋智  阅读(14)  评论(1)    收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示

目录导航