All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.azbh111.utils.java.datetime.DateTimeUtils Maven / Gradle / Ivy

package com.github.azbh111.utils.java.datetime;


import com.github.azbh111.utils.java.date.DateUtils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

/**
 * 基于java8 time api的封装
 * java8 time api所有类都是不可变得,线程安全的
 *
 * @author pyz
 * @date 2019/3/12 12:19 AM
 */
public class DateTimeUtils {
    /**
     * Hours per day.
     */
    public static final int HOURS_PER_DAY = 24;
    public static final int MAX_HOURS_OF_DAY = HOURS_PER_DAY - 1;
    /**
     * Minutes per hour.
     */
    public static final int MINUTES_PER_HOUR = 60;
    public static final int MAX_MINUTES_OF_HOUR = MINUTES_PER_HOUR - 1;
    /**
     * Minutes per day.
     */
    public static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY;
    public static final int MAX_MINUTES_OF_DAY = MINUTES_PER_DAY - 1;
    /**
     * Seconds per minute.
     */
    public static final int SECONDS_PER_MINUTE = 60;
    public static final int MAX_SECONDS_OF_MINUTE = SECONDS_PER_MINUTE - 1;
    /**
     * Seconds per hour.
     */
    public static final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
    public static final int MAX_SECONDS_OF_HOUR = SECONDS_PER_HOUR - 1;
    /**
     * Seconds per day.
     */
    public static final int SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;
    public static final int MAX_SECONDS_OF_DAY = SECONDS_PER_DAY - 1;
    /**
     * Milliseconds per day.
     */
    public static final int MILLIS_PER_DAY = SECONDS_PER_DAY * 1000;
    public static final int MAX_MILLIS_OF_DAY = MILLIS_PER_DAY - 1;
    /**
     * Microseconds per day.
     */
    public static final int MICROS_PER_DAY = SECONDS_PER_DAY * 1000_000;
    public static final int MAX_MICROS_OF_DAY = MICROS_PER_DAY - 1;
    /**
     * Nanos per second.
     */
    public static final int NANOS_PER_SECOND = 1000_000_000;
    public static final int MAX_NANOS_OF_SECOND = NANOS_PER_SECOND - 1;
    /**
     * Nanos per minute.
     */
    public static final long NANOS_PER_MINUTE = NANOS_PER_SECOND * SECONDS_PER_MINUTE;
    public static final long MAX_NANOS_OF_MINUTE = NANOS_PER_MINUTE - 1L;
    /**
     * Nanos per hour.
     */
    public static final long NANOS_PER_HOUR = NANOS_PER_MINUTE * MINUTES_PER_HOUR;
    public static final long MAX_NANOS_OF_HOUR = NANOS_PER_HOUR - 1L;
    /**
     * Nanos per day.
     */
    public static final long NANOS_PER_DAY = NANOS_PER_HOUR * HOURS_PER_DAY;
    public static final long MAX_NANOS_OF_DAY = NANOS_PER_DAY - 1L;

    public static final Clock SYSTEM_DEFAULT_ZONE_CLOCK = Clock.systemDefaultZone();
    public static final Clock UTC_CLOCK = Clock.systemUTC();
    public static final ZoneId SYSTEM_DEFAULT_ZONE_ID = SYSTEM_DEFAULT_ZONE_CLOCK.getZone();
    public static final ZoneId UTC_ZONE_ID = UTC_CLOCK.getZone();

    /**
     * DateTimeFormatter是线程安全的
     */
    private static final Map formatterCache = new ConcurrentHashMap<>();
    /**
     * 最常用的格式
     */
    private static final DateTimeFormatter hotDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final Pattern msPattern = Pattern.compile("\\d+");
    private static final Map standardDateTimeFormatters = new LinkedHashMap<>();

    static {
        standardDateTimeFormatters.put("LOCAL_DATE_TIME", hotDateTimeFormatter);
        standardDateTimeFormatters.put("ISO_INSTANT", DateTimeFormatter.ISO_INSTANT);
        standardDateTimeFormatters.put("ISO_LOCAL_DATE_TIME", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
        standardDateTimeFormatters.put("ISO_DATE_TIME", DateTimeFormatter.ISO_DATE_TIME);
        standardDateTimeFormatters.put("ISO_OFFSET_DATE_TIME", DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        standardDateTimeFormatters.put("ISO_ZONED_DATE_TIME", DateTimeFormatter.ISO_ZONED_DATE_TIME);
        standardDateTimeFormatters.put("RFC_1123_DATE_TIME", DateTimeFormatter.RFC_1123_DATE_TIME);

        standardDateTimeFormatters.putAll(DateUtils.standardDateFormatters);
    }

    public static Date toDate(LocalDate d, LocalTime t) {
        return toDate(d.atTime(t));
    }

    public static Date toDate(LocalDateTime dt) {
        return Date.from(dt.atZone(SYSTEM_DEFAULT_ZONE_ID).toInstant());
    }

    public static long toEpochSecond() {
        return toEpochSecond(now());
    }

    public static long toEpochSecond(Date d) {
        return toEpochSecond(from(d));
    }

    public static long toEpochSecond(LocalDateTime dt) {
        return dt.atZone(SYSTEM_DEFAULT_ZONE_ID).toEpochSecond();
    }


    public static LocalDateTime now() {
        return LocalDateTime.now();
    }

    public static LocalDateTime from(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), SYSTEM_DEFAULT_ZONE_ID);
    }

    /**
     * 来自 LocalDateTime.from
     * 增加了Instant的转换
     *
     * @param temporal
     * @return
     */
    public static LocalDateTime from(TemporalAccessor temporal) {
        if (temporal instanceof LocalDateTime) {
            return (LocalDateTime) temporal;
        } else if (temporal instanceof ZonedDateTime) {
            return ((ZonedDateTime) temporal).toLocalDateTime();
        } else if (temporal instanceof OffsetDateTime) {
            return ((OffsetDateTime) temporal).toLocalDateTime();
        } else if (temporal instanceof Instant) {
            return ((Instant) temporal).atZone(SYSTEM_DEFAULT_ZONE_ID).toLocalDateTime();
        }
        try {
            int year = temporal.get(ChronoField.YEAR);
            int month = temporal.get(ChronoField.MONTH_OF_YEAR);
            int day = temporal.get(ChronoField.DAY_OF_MONTH);
            int hour = temporal.isSupported(ChronoField.HOUR_OF_DAY) ? temporal.get(ChronoField.HOUR_OF_DAY) : 0;
            int minute = temporal.isSupported(ChronoField.MINUTE_OF_HOUR) ? temporal.get(ChronoField.MINUTE_OF_HOUR) : 0;
            int second = temporal.isSupported(ChronoField.SECOND_OF_MINUTE) ? temporal.get(ChronoField.SECOND_OF_MINUTE) : 0;
            int nano = temporal.isSupported(ChronoField.NANO_OF_SECOND) ? temporal.get(ChronoField.NANO_OF_SECOND) : temporal.isSupported(ChronoField.MILLI_OF_SECOND) ? temporal.get(ChronoField.MILLI_OF_SECOND) * 1000_000 : 0;
            return LocalDateTime.of(year, month, day, hour, minute, second, nano);
        } catch (DateTimeException ex) {
            throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " +
                    temporal + " of type " + temporal.getClass().getName(), ex);
        }
    }

    public static LocalDateTime startOfDay(LocalDate d) {
        return d.atStartOfDay();
    }

    public static LocalDateTime startOfDay(Date d) {
        return startOfDay(DateUtils.from(d));
    }

    public static LocalDateTime startOfDay() {
        return startOfDay(DateUtils.now());
    }

    public static LocalDateTime middleOfDay() {
        return middleOfDay(DateUtils.now());
    }

    public static LocalDateTime middleOfDay(Date d) {
        return middleOfDay(DateUtils.from(d));
    }

    public static LocalDateTime middleOfDay(LocalDate d) {
        return d.atTime(12, 0, 0, 0);
    }

    public static LocalDateTime endOfDay() {
        return endOfDay(DateUtils.now());
    }

    public static LocalDateTime endOfDay(Date d) {
        return endOfDay(DateUtils.from(d));
    }

    public static LocalDateTime endOfDay(LocalDate d) {
        return d.atTime(23, 59, 59, MAX_NANOS_OF_SECOND);
    }

    public static LocalDateTime startOfWeek(Date d) {
        return startOfWeek(DateUtils.from(d));
    }

    public static LocalDateTime startOfWeek() {
        return startOfWeek(DateUtils.now());
    }

    public static LocalDateTime startOfWeek(LocalDate d) {
        return startOfDay(DateUtils.firstDayOfWeek(d));
    }


    public static LocalDateTime endOfWeek(Date d) {
        return endOfWeek(DateUtils.from(d));
    }

    public static LocalDateTime endOfWeek() {
        return endOfWeek(DateUtils.now());
    }


    public static LocalDateTime endOfWeek(LocalDate d) {
        return endOfDay(DateUtils.lastDayOfWeek(d));
    }


    public static LocalDateTime startOfMonth(Date d) {
        return startOfMonth(DateUtils.from(d));
    }

    public static LocalDateTime startOfMonth() {
        return startOfMonth(DateUtils.now());
    }


    public static LocalDateTime startOfMonth(LocalDate d) {
        return startOfDay(DateUtils.firstDayOfWeek(d));
    }


    public static LocalDateTime endOfMonth(Date d) {
        return endOfMonth(DateUtils.from(d));
    }

    public static LocalDateTime endOfMonth() {
        return endOfMonth(DateUtils.now());
    }


    public static LocalDateTime endOfMonth(LocalDate d) {
        return endOfDay(DateUtils.lastDayOfMonth(d));
    }

    public static LocalDateTime startOfYear(Date d) {
        return startOfYear(DateUtils.from(d));
    }

    public static LocalDateTime startOfYear() {
        return startOfYear(DateUtils.now());
    }


    public static LocalDateTime startOfYear(LocalDate d) {
        return startOfDay(DateUtils.lastDayOfYear(d));
    }

    public static LocalDateTime endOfYear(Date d) {
        return endOfYear(DateUtils.from(d));
    }

    public static LocalDateTime endOfYear() {
        return endOfYear(DateUtils.now());
    }

    public static LocalDateTime endOfYear(LocalDate d) {
        return endOfDay(DateUtils.lastDayOfYear(d));
    }


    public static String format(String format) {
        return format(now(), format);
    }

    public static String format(Date d, String format) {
        return format(from(d), format);
    }

    public static String format(TemporalAccessor t, String format) {
        DateTimeFormatter f = getOrCreateDateTimeFormatter(format);
        return f.format(t);
    }

    public static LocalDateTime parse(String dateStr, String format) {
        DateTimeFormatter f = getOrCreateDateTimeFormatter(format);
        return LocalDateTime.parse(dateStr, f);
    }

    /**
     * 用常用格式尝试解析,支持时间戳解析
     * 若无法解析,抛出ParseException异常
     *
     * @param str
     * @return
     */
    public static LocalDateTime tryParse(String str) {
        if (str == null) {
            return null;
        }
        if (msPattern.matcher(str).matches()) {
            return from(Instant.ofEpochMilli(Long.valueOf(str)));
        }
        for (DateTimeFormatter formatter : standardDateTimeFormatters.values()) {
            TemporalAccessor t = null;
            LocalDateTime dt;
            try {
                t = formatter.parse(str, Instant::from);
                dt = from(t);
            } catch (Throwable e1) {
                try {
                    t = formatter.parse(str);
                    dt = from(t);
                } catch (DateTimeParseException e2) {
                    continue;
                }
            }
            return dt;
        }
        throw new com.github.azbh111.utils.java.datetime.DateTimeParseException("Unable to parse " + str + " to LocalDateTime");
    }

    public static DateTimeFormatter getOrCreateDateTimeFormatter(String format) {
        DateTimeFormatter f = formatterCache.get(format);
        if (f == null) {
            f = DateTimeFormatter.ofPattern(format);
            formatterCache.put(format, f);
        }
        return f;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy