oracle 日期格式化_新的日期时间API,优雅处理时间

点击上方蓝色“Java十年君”,选择“设为星标”。

e2a48d447d969772c9a0bd7f66623814.png

一、为什么要使用新日期时间


Java8之前的标准日期和时间存在以下缺陷:

  1. Date 可读性差        示例:Sat Nov 28 11:40:51 CST 2020
  2. SimpleDateFormat 是线程不安全的,多线程并发处理时会得到意想不到的结果
  3. Date 对日期的计算等操作处理比较繁琐,不够简洁

为解决上述缺陷,出现一些优秀三方日期处理框架,Joda-Time等。Joda-Time在Java 8之前成为Java的实际标准日期和时间库。

Java需要一套新的标准的日期时间API,于是在Java 8中引入的java.time包,遵守JSR310规范。

值得一提的是,Joda-Time的作者和Oracle一起共同参与了这些API的设计和实现。

二、新日期时间类


1、LocalDate: 当前日期,包含年月日,格式:yyyy-MM-dd
// 初始化
LocalDate nowLocalDate = LocalDate.now();
LocalDate localDate = LocalDate.of(2020,11,15);
LocalDate localDate = LocalDate.of(2020, Month.NOVEMBER,1);
// 获取当月中的天数
localDate.getDayOfMonth();
// 获取当年中的天数
localDate.getDayOfYear();
// 获取周中的天数
localDate.getDayOfWeek().getValue();
// 获取月份
localDate.getMonthValue();

2、LocalTime: 当前时间,包含时分秒,格式:HH:mm:ss
// 初始化
LocalTime localTime = LocalTime.now();
LocalTime localTime = LocalTime.of(12,10,20);
// 获取小时
localTime.getHour();
// 获取分钟
localTime.getMinute();
// 获取秒
localTime.getSecond();
// 获取纳秒
localTime.getNano();

3、LocalDateTime: 当前日期+时间 格式:yyyy-MM-dd'T'HH:mm:ss
// 当前日期+时间 yyyy-MM-dd'T'HH:mm:ss
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.now());
LocalDateTime localDateTime = LocalDateTime.of(2020, 11, 17, 20, 10, 9);
localDateTime.getDayOfMonth();
localDateTime.getDayOfYear();
4、Instant: 时间戳,精确到纳秒(Nano-Second),与我们常使用的System.currentTimeMillis()有些类似,System.currentTimeMillis()方法只精确到毫秒(Milli-Second)
Instant instant = Instant.now();
Instant instant = Instant.ofEpochSecond(1000L);
instant.getEpochSecond();
instant.toEpochMilli();
instant.getNano();
5、ZonedDateTime:特定时区的日期和时间
 格式示例:2020-11-28T11:52:20.200+08:00[Asia/Shanghai]
ZonedDateTime zonedDateTime = ZonedDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.now(), ZoneId.systemDefault());
ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDate.now(), LocalTime.now(), ZoneId.systemDefault());
ZonedDateTime zonedDateTime = ZonedDateTime.of(2020, 11, 16, 1, 1, 0, 0, ZoneId.systemDefault());
6、ZoneId:时区
// 当前系统默认时区
ZoneId zoneId = ZoneId.systemDefault();
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
// 查询全部可用时区
Set zoneIds = ZoneId.getAvailableZoneIds();
7、DateTimeFormatter:日期时间格式化
// 格式化
// yyyyMMdd
String dateStr1  = LocalDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE); 
//yyyy-MM-dd
String dateStr2  = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE); 
// yyyy-MM-dd'T'HH:mm:ss
String dateStr3  = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); 
 // HH:mm:ss
String dateStr4  = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME);
// 自定义格式
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateStr = LocalDateTime.now().format(dateTimeFormatter);
// 解析
LocalDateTime parseDate = LocalDateTime.parse("2020-11-28 11:11:22",dateTimeFormatter);
8、Duration:间隔,时间段
// 时间间隔
Duration duration = Duration.between(LocalDateTime.of(2020,11,15, 21,0,0),
        LocalDateTime.of(2020,11,16,1,1,0));
duration.getSeconds();
duration.toDays();
duration.toHours();
duration.getNano();
duration.toMinutes();
duration.toMillis();
duration.toNanos();
9、Period 间隔,时间段,仅支持年、月、日

区别:Period基于日期值,而Duration基于时间值

Period period = Period.between(LocalDate.now(), LocalDate.of(2020, 11, 16));
period.getYears();
period.getMonths();
period.getDays();

10、日期比较
// 判断是否在指定日期之后
localDateTime.isAfter(LocalDateTime.now());
// 判断是否在指定日期之前
localDateTime.isBefore(LocalDateTime.now());
// 判断是否和指定日期相等
localDateTime.isEqual(LocalDateTime.now());
// 和指定日期比较,负数是小,0 时等于 ,正数是大
localDateTime.compareTo(LocalDateTime.now());
11、日期操作:增加,减小,修改
// 减小
localDateTime.minusYears(1L);
localDateTime.minusMonths(1L);
localDateTime.minusWeeks(1L);
localDateTime.minusDays(1L);
localDateTime.minusHours(1L);
localDateTime.minusMinutes(1L);
localDateTime.minusSeconds(1L);
localDateTime.minusNanos(1L);
// 增加
localDateTime.plusYears(1L);
localDateTime.plusMonths(1L);
localDateTime.plusWeeks(1L);
localDateTime.plusDays(1L);
localDateTime.plusHours(1L);
localDateTime.plusMinutes(1L);
localDateTime.plusSeconds(1L);
localDateTime.plusNanos(1L);
// 修改
LocalDateTime localDateTime = LocalDateTime.now();
localDateTime = localDateTime.withYear(2019);
localDateTime = localDateTime.withMonth(1);
localDateTime = localDateTime.withDayOfMonth(1);
localDateTime = localDateTime.withDayOfYear(1);
localDateTime = localDateTime.withHour(1);
localDateTime = localDateTime.withMinute(1);
localDateTime = localDateTime.withSecond(30);
12、更复杂的时间操作,使用TemporalAdjuster

TemporalAdjuster是函数接口,调整Temporal对象的策略,在TemporalAdjusters中有预定义的实现,同时也可自定义实现。

使用示例:

//获取下个月的第一天
LocalDateTime firstDayOfNextMonth = LocalDateTime.now().with(TemporalAdjusters.firstDayOfNextMonth());

预定义实现:

// 当月第一天
TemporalAdjusters.firstDayOfMonth();
// 下月第一天
TemporalAdjusters.firstDayOfNextMonth();
// 当年第一天
TemporalAdjusters.firstDayOfYear();
// 下年的第一天
TemporalAdjusters.firstDayOfNextYear();
// 当月的最后一天
TemporalAdjusters.lastDayOfMonth();
// 当年的最后一天
TemporalAdjusters.lastDayOfYear();
// 当月的最后一个星期几
TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY);
// 当月的最开始一个星期几
TemporalAdjusters.firstInMonth(DayOfWeek.FRIDAY);
// 后一个星期几
TemporalAdjusters.next(DayOfWeek.MONDAY);
// 前一个星期几
TemporalAdjusters.previous(DayOfWeek.MONDAY);
// 返回后一个给定的星期几,如果这个值满足条件,直接返回
TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY);
// 返回前一个给定的星期几,如果这个值满足条件,直接返回
TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY);
// 返回同一个月中每周的第几天
TemporalAdjusters.dayOfWeekInMonth(1,DayOfWeek.MONDAY);

自定义实现:

//自定义,14天后的日期
LocalDateTime.now().with(temporal -> {
    return temporal.plus(14, ChronoUnit.DAYS);
});

三、时间类之间的关系和相互转换


1892f1c5b1ed9eeb93f23bf970812560.png

转换关系:

// localDate + localTime <=> localDateTime
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.of(localDate,localTime);

// LocalDateTime + ZoneId <=> ZonedDateTime
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime,zoneId);

// Instant+ ZoneId <=> ZonedDateTime
Instant instant = zonedDateTime.toInstant();
ZonedDateTime zonedDateTime = instant.atZone(zoneId);

// Date  <=> Instant
Date date = Date.from(instant);
Instant instant = date.toInstant();
//LocalDateTime -> Date
Date date =  Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());

// Date -> LocalDateTime
LocalDateTime localDateTime=(new Date()).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

四、小结


JAVA8提供的日期时间对象是不可变对象。日期操作会返回一个新的实例,老的日期时间对象不会发生改变。

支持精细化的操作日期和时间。

新日期时间类之间转换更加简洁,清晰。

快来一起使用新的日期时间API,优雅的处理时间。

扫一扫,关注我,获取更多优质内容
e0c2ccaf21df650be39962d673a6c2f4.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值