时间日期

package cn.anzhongwei.lean.demo.date;


import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

public class DateUtils {
    private static final DateTimeFormatter YEAH_MONTH_DAY = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter YEAH_MONTH_DAY_HOUR_MINUTE_SECOND = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public DateUtils() {
    }

    public static void main(String[] args) {

        System.out.println("1. 获取当前日期字符串: " + getNowDateTime());
//
        System.out.println("2.1 获取UTC时间: " + getUTCTime());

        System.out.println("2.2 获取时间戳: " + getTimestamp());
//
        System.out.println("3. 根据字符串日期转LocalDate: " + getString2LocalDate("2019-01-01"));

        System.out.println("4. 根据字符串日期时间转 LocalDateTime: " + getString2FullDate("2019-01-01 00:00:00"));

        System.out.println("5. 根据自定义格式获取当前日期: " + getNowDateByFormatter("yyyy++MM++dd"));

        System.out.println("6. 根据自定义格式获取当前日期时间: " + getNowDateTimeByFormatter("yyyy++MM++dd HH:mm:ss"));

        System.out.printf(
                """
                            7. 根据节点获取当前日期时间信息
                            %s 年 %s 月 %s 日 星期 %s 是今年的第%s天
                            %s时 %s分 %s秒
                        %n""", getNowDateNode(DateEnum.YEAR),
                getNowDateNode(DateEnum.MONTH),
                getNowDateNode(DateEnum.DAY),
                getNowDateNode(DateEnum.WEEK),
                getNowDateNode(DateEnum.DAYOFYEAR),
                getNowDateNode(DateEnum.HOUR),
                getNowDateNode(DateEnum.MINUTE),
                getNowDateNode(DateEnum.SECOND)
        );

        System.out.println("8. 一年后的日期时间: " + getPreOrAfterDateTime(DateEnum.YEAR, 1));
        System.out.println("8. 一年前的日期时间: " + getPreOrAfterDateTime(DateEnum.YEAR, -1));

        System.out.println("8. 一小时后的日期时间: " + getPreOrAfterDateTime(DateEnum.HOUR, 1));
        System.out.println("8. 一小时前的日期时间: " + getPreOrAfterDateTime(DateEnum.HOUR, -1));

        System.out.println("9. 比较两个日期时间大小 2019-01-01 00:00:00  & 2019-01-01 00:00:01: " + compareDateTime("2019-01-01 00:00:00", "2019-01-01 00:00:01"));

        System.out.println("10. 判断是否闰年: " + isLeapYear("2024-01-01"));

        System.out.println("11. 两个日期间隔天数: " + getPeridNum("2019-01-01", "2019-01-01", DateEnum.DAY));

        System.out.println("12. 获取当前时区:" + getTimeZone());

        System.out.println("13. 获取America/Los_Angeles时区时间 ZoneId.SHORT_IDS:" + getTimeZoneDateTime("America/Los_Angeles"));
    }



    // 1. 获取当前日期时间字符串
    // 改成LocalDate.now().toString() 获取当前日期字符串
    // 改成LocalTime.now().toString() 获取当前时间字符串
    public static String getNowDateTime() {
        return LocalDateTime.now().format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
    }

    // 2.1 获得utd时间
    public static String getUTCTime() {
        //Clock类
        return Clock.systemUTC().instant().toString();
    }

    // 2.2 获得时间戳
    public static Long getTimestamp() {
        //Clock类
        return Clock.systemUTC().millis();
    }

    // 3. 根据字符串日期转LocalDate
    public static LocalDate getString2LocalDate(String date) {
        return LocalDate.parse(date, YEAH_MONTH_DAY);
    }

    // 4. 根据字符串日期时间转 LocalDateTime
    public static LocalDateTime getString2FullDate(String date) {
        return LocalDateTime.parse(date, YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
    }

    // 5. 根据自定义格式获取当前日期
    public static String getNowDateByFormatter(String formatterPattern) {
        return LocalDate.now().format(DateTimeFormatter.ofPattern(formatterPattern));
    }

    // 6. 根据自定义格式获取当前日期时间
    public static String getNowDateTimeByFormatter(String formatterPattern) {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(formatterPattern));
    }

    // 7. 获取当前 节点
    public static Integer getNowDateNode(DateEnum dateEnum) {
        LocalDateTime nowDate = LocalDateTime.now();
        Integer nowNode = null;
        switch (dateEnum) {
            case YEAR:
                nowNode = nowDate.getYear();
                break;
            case MONTH:
                nowNode = nowDate.getMonthValue();
                break;
            case WEEK:
                nowNode = conversionWeek2Num(DateUtils.WeekEnum.valueOf(nowDate.getDayOfWeek().toString()));
                break;
            case DAY:
                nowNode = nowDate.getDayOfMonth();
                break;
            case DAYOFYEAR:
                nowNode = nowDate.getDayOfYear();
                break;
            case HOUR:
                nowNode = nowDate.getHour();
                break;
            case MINUTE:
                nowNode = nowDate.getMinute();
                break;
            case SECOND:
                nowNode = nowDate.getSecond();
        }

        return nowNode;
    }

    // 8. 从当前日期加或减一个 年 月 日 周 时 分 秒 的时间 加就是正数 减就是负数
    // LocalDateTime nowDate = LocalDateTime.now();
    // 改成 LocalDate nowDate = LocalDate.now(); 就是只能获取 年月日周
    // 改成 LocalTime nowDate = LocalTime.now(); 就是只能获取 时 分 秒
    public static String getPreOrAfterDateTime(DateEnum dateEnum, long time) {
        LocalDateTime nowDate = LocalDateTime.now();
        switch (dateEnum) {
            case YEAR:
                // 从api 的角度也可以用 这个api提供的时间单位更多
//                nowDate.plus(time, ChronoUnit.YEARS);
//                nowDate.minus(time, ChronoUnit.YEARS)
                return nowDate.plusYears(time).format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
            case MONTH:
                return nowDate.plusMonths(time).format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
            case WEEK:
                return nowDate.plusWeeks(time).format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
            case DAY:
                return nowDate.plusDays(time).format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
            case DAYOFYEAR:
                throw new RuntimeException("不支持的选项");
            case HOUR:
                return nowDate.plusHours(time).format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
            case MINUTE:
                return nowDate.plusMinutes(time).format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
            case SECOND:
                return nowDate.plusSeconds(time).format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
            default:
                throw new RuntimeException("不支持的选项");
        }
    }

    // 9. 比较日期时间 begin 比 end 早 返回true
    // 同理LocalDate比较日期  LocalTime 比较时间
    public static boolean compareDateTime(String begin, String end) {
        LocalDateTime beginDate = LocalDateTime.parse(begin, YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
        LocalDateTime endDate = LocalDateTime.parse(end, YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
        return beginDate.isBefore(endDate);
    }

    // 10. 判断是否闰年
    public static boolean isLeapYear(String date) {
        return LocalDate.parse(date.trim()).isLeapYear();
    }

    // 11. 获取两个日期之间的间隔 这个函数只能用LocalDate
    public static Integer getPeridNum(String begin, String end, DateEnum dateEnum) {
        switch (dateEnum) {
            case YEAR:
                return Period.between(LocalDate.parse(begin), LocalDate.parse(end)).getYears();
            case MONTH:
                return Period.between(LocalDate.parse(begin), LocalDate.parse(end)).getMonths();
            case WEEK:
                throw new RuntimeException("不支持的参数");
            case DAY:
                return Period.between(LocalDate.parse(begin), LocalDate.parse(end)).getDays();
            default:
                throw new RuntimeException("不支持的参数");
        }
    }

    // 12. 获取当前时区
    public static String getTimeZone() {
        return ZoneId.systemDefault().toString();
    }

    // 13. 获取指定时区时间 ZoneId.SHORT_IDS
    public static String getTimeZoneDateTime(String timeZone) {
        return LocalDateTime.now(ZoneId.of(timeZone)).format(YEAH_MONTH_DAY_HOUR_MINUTE_SECOND);
    }




    public static int conversionWeek2Num(WeekEnum weekEnum) {
        switch (weekEnum) {
            case MONDAY:
                return 1;
            case TUESDAY:
                return 2;
            case WEDNESDAY:
                return 3;
            case THURSDAY:
                return 4;
            case FRIDAY:
                return 5;
            case SATURDAY:
                return 6;
            case SUNDAY:
                return 7;
            default:
                return -1;
        }
    }

    public static enum WeekEnum {
        MONDAY,
        TUESDAY,
        WEDNESDAY,
        THURSDAY,
        FRIDAY,
        SATURDAY,
        SUNDAY;

        private WeekEnum() {
        }
    }

    public static enum DateEnum {
        YEAR,
        MONTH,
        WEEK,
        DAY,
        HOUR,
        MINUTE,
        SECOND,
        DAYOFYEAR;

        private DateEnum() {
        }
    }
}