java 时间转换之LocalDate,LocalTime ,LocalDateTime的使用篇二

    技术2022-07-21  69

    上一篇说了 LocalDate,LocalTime ,LocalDateTime的基础使用; 本文主要是说LocalDate,LocalTime ,LocalDateTime的比较,特殊时间格式的处理,一段时间的获取,以及设置时区问题

    1、首先写一些基础方法

    /** * 指定时间住那换为时间戳 * @param time 只能是时间格式,例如 HH:mm:ss、HH:mm、mm:ss 15:30:55、15:30、30:55 * @param formatter HH:mm:ss、HH:mm、mm:ss * @return */ public long stringTimeToLong(String time,DateTimeFormatter formatter){ return LocalTime.parse(time,formatter).atDate(LocalDate.now()).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } /** * 指定日期转换为时间戳 * @param date 只能是日期格式。例如 yyyy-MM-dd、MM-dd、yyyy-MM等 2020-07-01、2020-07、07-01 * @param formatter * @return */ public long stringDateToLong(String date,DateTimeFormatter formatter){ return LocalDate.parse(date, formatter).atTime(LocalTime.now()).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } /** * 指定日期时间转换为时间戳 * @param dateTime 可以是任何时间格式 例如 yyyy-MM-dd HH:mm:ss、yyyy-MM-dd、HH:mm:ss、MM-dd HH:mm等 2020-07-01 15:30:55、 07-01 15:30、 2020-07-01、 15:30:55 * @param formatter yyyy-MM-dd HH:mm:ss、yyyy-MM-dd、HH:mm:ss、MM-dd HH:mm * @return */ public long stringToLong(String dateTime, DateTimeFormatter formatter){ return LocalDateTime.parse(dateTime, formatter).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } /** * long 转 LocalDate * @param l * @return */ public LocalDate longToDate(long l){ return LocalDateTime.ofInstant(Instant.ofEpochMilli(l), ZoneId.systemDefault()).toLocalDate(); } /** * long 转 LocalTime * @param l * @return */ public LocalTime longToLocalTime(long l){ return LocalDateTime.ofInstant(Instant.ofEpochMilli(l),ZoneId.systemDefault()).toLocalTime(); } /** * long 转 LocalDateTime * @param l * @return */ public LocalDateTime longToDateTime(long l){ return LocalDateTime.ofInstant(Instant.ofEpochMilli(l),ZoneId.systemDefault()); } /** * LocalDate 转 LocalDateTime * @return */ public LocalDateTime dateToDateTime(){ return LocalDate.now().atTime(LocalTime.now()); } /** * LocalTime 转 LocalDateTime * @return */ public LocalDateTime timeToDateTime(){ return LocalTime.now().atDate(LocalDate.now()); } /** * 格式化时间戳 * @param l * @param formatter * @return */ public String longToTime(long l,DateTimeFormatter formatter){ LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(l), ZoneId.systemDefault()); return dateTime.format(formatter); } public String longToLocalDateTime(long l,DateTimeFormatter formatter){ return longToDate(l).format(formatter); } public String longToLocalTimeTime(long l,DateTimeFormatter formatter){ return longToLocalTime(l).format(formatter); }

    2、获取特殊事件格式1 07-01(今天) 15:30,像这种时间带有 前天 昨天  今天 明天 后天 格式 在平时工作中是很常见的,但是系统并没有给我们提供方法,但可以通过日期对比进行迂回解决

     

     

    /** * 时间比较 * 获取中文日期 前天 昨天 今天 明天 后天 等 * @param * @param endTime * @return */ public String getChineseDate(long endTime){ LocalDate startDate = LocalDate.now(); LocalDate endDate = longToDate(endTime); String date = ""; switch (startDate.compareTo(endDate)) { case -2: date = "(前天)"; break; case -1: date = "(昨天)"; break; case 0: date = "(今天)"; break; case 1: date = "(明天)"; break; case 2: date = "(后天)"; break; } return date; } /** * 获取特殊事件格式1 07-01(今天) 15:30 */ public String getDateTime(long time){ String date = getChineseDate(time); return longToLocalDateTime(time,DateTimeFormatter.ofPattern(TimeFormat.DATE_MD_DOUBLE)) + date + longToLocalTimeTime(time, DateTimeFormatter.ofPattern(TimeFormat.TIME_HM_DOUBLE)); }

    3、获取一段时间,在java 8以下获取一个时间段是非常繁琐的,并且需要自己判断年份和月份以及每月多少天,而LocalDate 则并不需要,我写了两个方法,一个是获取固定时间段,一个是获取固定时长的时间段,供大家参考

    /** * 获取一段时间 * @param startDay 开始日期 * @param endDay 结束日期 * @return */ public List<String> getListDate(String startDay,String endDay,DateTimeFormatter formatter){ List<String> days = new ArrayList<>(); LocalDate start = LocalDate.parse(startDay); LocalDate end = LocalDate.parse(endDay); long between = ChronoUnit.DAYS.between(start, end); if (between < 1){ return days; } Stream.iterate(start,s -> {return s.plusDays(1);}).limit(between + 1).forEach(f -> {days.add(f.toString());}); return days; } /** * 获取一段时间 * @param dayCount 日期间隔 * @return */ public List<String> getListDate(int dayCount){ List<String> days = new ArrayList<>(); LocalDate start = LocalDate.now(); LocalDate end = start.plusDays(dayCount); start.format(DateTimeFormatter.ofPattern(TimeFormat.DATE_MD_DOUBLE)); end.format(DateTimeFormatter.ofPattern(TimeFormat.DATE_MD_DOUBLE)); long between = ChronoUnit.DAYS.between(start, end); if (between < 1){ return days; } Stream.iterate(start,s -> {return s.plusDays(1);}).limit(between + 1).forEach(f -> {days.add(f.toString());}); return days; } public List<String> getListTime(String startTime,String endTime,DateTimeFormatter formatter){ List<String> times = new ArrayList<>(); LocalTime start = LocalTime.parse(startTime); LocalTime end = LocalTime.parse(endTime); long between = ChronoUnit.HOURS.between(start, end); if (between < 1){ return times; } Stream.iterate(start,s -> {return s.plusHours(1);}).limit(between + 1).forEach(f -> {times.add(f.toString());}); return times; }

     

    4、设置时区问题,大家都发现了,我们在获取时间的时候使用的System.currentTimeMillis() 获取的是系统时间,在进行时间格式化的时候会存在获取时间和格式化时间不一样的问题,这时候就要注意时区了。

    关键类ZoneId使用这个类进行时区设置;

    ZoneId.systemDefault(); 系统默认事件 ZoneId.of("Asia/Shanghai") 亚洲/上海时间 ZoneId.of("Asia/Beijing") 亚洲/上海时间

    既可以解决系统设置时区以后,获取系统时间和解析出的结果不对的情况。

    本文完,欢迎大家指导讨论;

     

    Processed: 0.010, SQL: 9