美文网首页
优雅编程 - 日期处理

优雅编程 - 日期处理

作者: 林昀熙 | 来源:发表于2019-12-19 11:06 被阅读0次

日期格式化

java.util.date和java.time.LocalDateTime格式化

应用示例

/**
* 格式化日期
* @param date 待格式化的日期
* @param pattern 格式化正则
* @return 格式化结果串
*/
public static String format(Date date, String pattern){
   return new SimpleDateFormat(pattern).format(date);
}

/**
* 格式化日期
* @param localDateTime 待格式化的日期
* @param pattern 格式化正式
* @return 格式化结果串
*/
public static String format(LocalDateTime localDateTime, String pattern){
   return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
}

/**
* 格式化日期
* @param localDate 待格式化的日期
* @param pattern 格式化正则, 这里使用的类型 {@link LocalDate}, 所以正则只能设定到天
* @return 格式化结果串
*/
public static String format(LocalDate localDate, String pattern){
   return localDate.format(DateTimeFormatter.ofPattern(pattern));
}

示例测试

// 2017-08-28 15:45:02
System.out.println(format(new Date(), "yyyy-MM-dd HH:mm:ss"));
// 2017-08-28 15:45:02
System.out.println(format((LocalDateTime.now()), "yyyy-MM-dd HH:mm:ss"));
// 2017-08-28
System.out.println(format((LocalDateTime.now().toLocalDate()), "yyyy-MM-dd"));

日期转换

java.util.date和java.time.LocalDateTime互相转换

应用示例

/**
* 将 {@link LocalDateTime} 转换成 {@link Date}
* @param localDateTime {@link LocalDateTime} 待转换的日期
* @return 转换成Date结果
*/
public static Date from(LocalDateTime localDateTime){
   Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
   return Date.from(instant);
}

/**
* 将 {@link Date} 转换成 {@link LocalDateTime}
* @param date {@link Date} 待转换的日期
* @return 转换成 {@link LocalDateTime} 结果
*/
public static LocalDateTime from(Date date){
   return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}

示例测试

String patternTime = "yyyy-MM-dd HH:mm:ss";
Date now = new Date();
// 2017-08-28 14:47:10
System.out.println(format(from(now), patternTime));
// 2017-08-28 14:47:10
System.out.println(format(from(LocalDateTime.now()), patternTime));

区间集合

计算两端日期之间内的日期天数集合

示例代码

/**
* 获取{@link Date}在开始时间和结束时间内的日期时间段{@link Date}集合
* @param start 开始时间
* @param end 结束时间
* @return 时间天数集合
*/
public static List<Date> dateZones(Date start, Date end){
   return dateZones(from(start), from(end));
}


/**
* 获取 {@link LocalDate} 在开始时间和结束时间内的日期时间段 {@link LocalDate} 集合
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List<Date> dateZones(LocalDate start, LocalDate end){
   return Stream.iterate(start, x -> x.plusDays(1))
           .limit(ChronoUnit.DAYS.between(start, end) + 1)
           .map(e -> Date.from(e.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))
           .collect(Collectors.toList());
}

    
/**
* 获取{@link LocalDateTime} 在开始时间和结束时间内的日期时间段{@link Date}集合
* @param start 开始时间
* @param end 结束时间
* @return 时间天数集合
*/
public static List<Date> dateZones(LocalDateTime start, LocalDateTime end){
   // 用起始时间作为流的源头,按照每次加一天的方式创建一个无限流
   return Stream.iterate(start.toLocalDate(), x -> x.plusDays(1))
           // 截断无限流,长度为起始时间和结束时间的差+1个
           .limit(ChronoUnit.DAYS.between(start, end) + 1)
           // 由于最后要的是字符串,所以map转换一下
           .map(e -> Date.from(e.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))
           // 把流收集为List
           .collect(Collectors.toList());
}


/**
* 获取{@link Date}在开始时间和结束时间内的日期时间段{@link LocalDate}集合
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List<LocalDate> localDateZones(Date start, Date end){
   return localDateZones(from(start), from(end));
}


/**
* 获取 {@link LocalDate} 在开始时间和结束时间内的日期时间段 {@link LocalDate} 集合
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List<LocalDate> localDateZones(LocalDate start, LocalDate end){
   return Stream.iterate(start, x -> x.plusDays(1))
           .limit(ChronoUnit.DAYS.between(start, end) + 1)
           .collect(Collectors.toList());
}

/**
* 获取 {@link LocalDateTime} 在开始时间和结束时间内的日期时间段 {@link LocalDate} 集合
* @param start 开始时间
* @param end 结束时间
* @return 时间集合
*/
public static List<LocalDate> localDateZones(LocalDateTime start, LocalDateTime end){
   // 用起始时间作为流的源头,按照每次加一天的方式创建一个无限流
   return Stream.iterate(start.toLocalDate(), x -> x.plusDays(1))
           // 截断无限流,长度为起始时间和结束时间的差+1个
           .limit(ChronoUnit.DAYS.between(start, end) + 1)
           .map(e -> e.atStartOfDay().toLocalDate())
           // 把流收集为List
           .collect(Collectors.toList());
}

示例测试

String patternDate = "yyyy-MM-dd";
List<Date> dateList = Arrays.asList(new Date(2017-1900, 11, 30), new Date(2018-1900, 0, 3));

// 2017-12-30
System.out.println("开始时间:"  + format(dateList.get(0), patternDate) + ", 结束时间:" + format(dateList.get(1), patternDate));

// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(dateZones(dateList.get(0), dateList.get(1)).stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));
// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(localDateZones(dateList.get(0), dateList.get(1)).stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));


LocalDateTime now = LocalDateTime.of(2017, Month.DECEMBER, 30, 0, 0, 0);

// 2017-12-30
System.out.println(format(now, patternDate));

// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(dateZones(now, now.plus(4, ChronoUnit.DAYS))
      .stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));

// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(localDateZones(now, now.plus(4, ChronoUnit.DAYS))
      .stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));

// [2017-12-30, 2017-12-31, 2018-01-01, 2018-01-02, 2018-01-03]
System.out.println(localDateZones(now.toLocalDate(), now.toLocalDate().plus(4, ChronoUnit.DAYS))
      .stream().map(x -> format(x, patternDate)).collect(Collectors.toList()));

日期加减

示例代码

String patternDate = "yyyy-MM-dd HH:mm:ss";

LocalDateTime now = LocalDateTime.of(2017, Month.DECEMBER, 30, 0, 0, 0);

// 当前时间: 2017-12-30 00:00:00
System.out.println("当前时间: " + format(now, patternDate));

// 30秒前: 2017-12-29 23:59:30
System.out.println("30秒前: " + format(now.plus(-30, ChronoUnit.SECONDS), patternDate));

// 5分钟后: 2017-12-30 00:05:00
System.out.println("5分钟后: " + format(now.plus(5, ChronoUnit.MINUTES), patternDate));

// 2天前: 2017-12-28 00:00:00
System.out.println("2天前: " + format(now.plus(-2, ChronoUnit.DAYS), patternDate));

// 2天后: 2018-01-01 00:00:00
System.out.println("2天后: " + format(now.plus(2, ChronoUnit.DAYS), patternDate));

// 1周后: 2018-01-06 00:00:00
System.out.println("1周后: " + format(now.plusWeeks(1), patternDate));
        
// 1月前: 2017-11-30 00:00:00
System.out.println("1月前: " + format(now.plus(-1, ChronoUnit.MONTHS), patternDate));

// 1月后: 2018-01-30 00:00:00
System.out.println("1月后: " + format(now.plus(1, ChronoUnit.MONTHS), patternDate));

// 1年后: 2018-12-30 00:00:00
System.out.println("1年后: " + format(now.plus(1, ChronoUnit.YEARS), patternDate));

日期推算

示例代码

String patternDate = "yyyy-MM-dd";

LocalDateTime now = LocalDateTime.of(2017, Month.DECEMBER, 30, 0, 0, 0);

// 当前时间: 2017-12-30
System.out.println("当前时间: " + format(now, patternDate) + " ,是否闰年: " + now.toLocalDate().isLeapYear());

// 当前月份: 十二月
System.out.println("当前月份: " + Month.from(now).getDisplayName(TextStyle.FULL, Locale.CHINA));

// 当前星期: 星期六
System.out.println("当前星期: " + DayOfWeek.from(now).getDisplayName(TextStyle.FULL, Locale.CHINA));

// 需要注意:java8提供的获取的本周第一天和本周最后一天是西方的界定方式, 第一天是周末, 最后一天是周六, 和中国的不太一样
// 本周初第一天:2017-12-24
System.out.println("本周初第一天: " + format(now.with(WeekFields.of(Locale.CHINA).dayOfWeek(),1L), patternDate));

// 本周最后一天:2017-12-30
System.out.println("本周最后一天: " + format(now.with(WeekFields.of(Locale.CHINA).dayOfWeek(),7L), patternDate));

// 本月初第一天:2017-12-01
System.out.println("本月初第一天: " + format(now.with(TemporalAdjusters.firstDayOfMonth()), patternDate));

// 本月最后一天:2017-12-31
System.out.println("本月最后一天: " + format(now.with(TemporalAdjusters.lastDayOfMonth()), patternDate));

// 本年最后一天:2017-01-01
System.out.println("本年最后一天: " + format(now.with(TemporalAdjusters.firstDayOfYear()), patternDate));

// 本年最后一天:2017-12-31
System.out.println("本年最后一天: " + format(now.with(TemporalAdjusters.lastDayOfYear()), patternDate));

相关文章

  • 优雅编程 - 日期处理

    日期格式化 java.util.date和java.time.LocalDateTime格式化 应用示例 示例测试...

  • Python:如何用一行代码获取上个月是几月

    本文介绍的关于Python时间日期处理,日期时间处理在实际应用场景中无处不在,所以这也成了编程语言中必不可少的模块...

  • 阿里Java编程规约【五】日期处理

    1.【强制】日期格式化时,传入 pattern 中表示年份统一使用小写的 y。说明:日期格式化时,yyyy 表示当...

  • 《一步一步学优雅编程》目录

    优雅编程之这样注释代码,你就“正常”了(一) 优雅编程之这样写函数,你就“正常”了(二) 优雅编程之做1个“正常”...

  • 日期处理

    设计表时,日期类型尽量还是选varchar类型,要相信数据库的强大,完全可以转换。

  • 日期处理

    时间格式 yyyy-MM-dd HH:mm 日历部分 较乱 补充

  • 日期处理

    判断是否为今年 取出日期的年份进行比较,如果一样返回1,不一样就返回0。 判断是否为今天 取出当前日期和要比较日期...

  • 日期处理

    还有显示年份 具体代码 写两个分类 分类一: NSCalendar 二 . 分类二: NSDate 在模型里...

  • 日期处理

    日志中出现的时间格式如下:[24/Jun/2019:21:00:03 +0800]之前使用的字符串匹配的方式,得到...

  • egg.js设计思路

    理想的企业级Web开发模型 错误处理(优雅的退出) 多进程管理(egg-cluster) 编程模型的约束(egg-...

网友评论

      本文标题:优雅编程 - 日期处理

      本文链接:https://www.haomeiwen.com/subject/sklmnctx.html