新增日期时间API
在JDK8中新增加了java.time包
是JSR310规范的实现,它的目的是弥补旧的日期/时间API实现中所有缺陷。
新的时间日期API的特点和设计原则:
- 不变性:新的日期时间API中,所有的类都是不可变的,这种设计有利于并发编程
- 关注点分离:新的API将人可读的日期时间和机器时间明确分离,为日期(Date)、时间(Time)、日期时间(DateTime)、时间戳(unix timestamp)以及时区定义了不同的类
- 清晰:在所有类中,方法都被明确定义用以完成相同行为。所有类都使用了工厂模式和策略模式,使用了其中某个类的方法,与其他类协同工作并不困难
- 实用操作:所有新的日期时间API都实现了一系列方法用于完成通用的任务,如:加、减、格式化、解析、从日期时间中提取单独部分等操作
- 可扩展性:所有的日期时间API工作在ISO-8601日历系统上的,但是我们也可以将其应用在非IOS的日历上
常用类:
- Clock(时钟)
- Duration(时间段)
- Instant(时间点)
- Timezones(时区)
- LocalDate(本地日期)
- LocalTime(本地时间)
- Local Data Time(本地日期时间)
- DateTimeFormatter(格式化时间)
- Year、YearMonth、MonthDay
Clock
用于获取指定时区的当前日期、时间。该类可以替换System类中的currentTimeMills()方法,而且提供了更多方法来获取当前日期、时间。该类中有大量的静态方法来获取Clock对象
Clock clock = Clock.systemUTC();
System.out.println("获取当前时间毫秒:" + clock.millis());
System.out.println("获取格林尼治标准时间:"+clock.instant());
Duration
表示持续时间,该类可以方便的获取一段时间
Duration duration = Duration.ofDays(1);
System.out.println("一天有:"+duration.toHours()+"个小时");
System.out.println("一天有:"+duration.toMinutes()+"分钟");
System.out.println("一天有:"+duration.toSeconds()+"秒");
Instant
代表一个具体的时刻,可以精确到纳秒。该类提供了静态的now()方法来获取当前时刻,静态的now(Clock clock)方法来获取clock对应的时刻,一系列minusXxx()方法在当前时刻基础上减去一段时间,plusXxx方法在当前时刻减去一段时间(Xxx可以是Seconds秒、Millis毫秒、Nanos纳秒)
//返回当前时间的时间戳
Instant instant = Instant.now();
System.out.println("当前时间戳:"+instant);
//instant减少10分钟
System.out.println(instant.minusSeconds(600));
//instant增加一小时
System.out.println(instant.plusMillis(3600000));
Timezones
表示时区偏移量。静态方法getDefault()获取默认的TimeZone,getTimeZone(String id)方法获取指定的时区。
TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");
//返回当前时区名称
System.out.println(timeZone.getDisplayName());
LocalDate
表示本地的日期(不带时区)。支持加减操作年、月、日、星期。
LocalDate localDate = LocalDate.now();
System.out.println("本地日期"+localDate);
System.out.println("增加一星期:"+localDate.plusWeeks(1));
//获得2008年的第221天
LocalDate localDate2 = LocalDate.ofYearDay(2008,221);
System.out.println(localDate2);
LocalTime
表示本地时间(不带时区)。支持加减操作小时、分钟、秒。
LocalTime localTime = LocalTime.now();
System.out.println("本地时间:"+localTime);
System.out.println("减去一小时:"+localTime.minusHours(1));
//11点11分11秒
LocalTime localTime2 = LocalTime.of(11,11,11);
System.out.println(localTime2);
LocalDataTime
表示本地的日期时间(不带时区)。支持加减操作年、月、日、小时、分钟、秒。
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("本地日期时间:"+localDateTime);
LocalDateTime ldt = localDateTime.plusDays(1).plusHours(12);
System.out.println("增加一天零12个小时后:"+ldt);
Year、YearMonth、MonthDay
Year表示年(2020),YearMonth表示年月(2020-10)、MonthDay表示月日(10-2)
Year year = Year.now();
System.out.println("当前年份加五:"+year.plusYears(5));
//使用year中的方法,根据指定的月份获得YearMonth
YearMonth yearMonth = year.atMonth(12);
System.out.println(yearMonth);
MonthDay monthDay = MonthDay.now();
System.out.println(monthDay);
DateTimeFormatter
日期时间格式化类。相当于DateFormat、SimpleDateFormat的整合,功能强大。
为了使用使用DateTimeFormatter进行格式化解析,就要先获取DataTimeFormatter对象:
- 使用DateTimeFormatter中大量的静态常量来描述格式化样式,这些常量就是DateTimeFormatter实例对象。
- 使用FormatStyle枚举中的枚举值创建DateTimeFormatter对象。(四种风格:FULL、LONG、MEDIUM、SHORT)
- 根据模式字符串创建DateTimeFormatter对象。
将日期时间格式化为字符串可以使用两种方式:
- 调用DateTimeFormatter的format(TemporalAccessor temporal)方法进行格式化。(LocalDate、LocalDateTime、LocalTime等类都是TemporalAccessor接口的实现类)
- 调用LocalDate、LocalDateTime、LocalTime等日期、时间对象的format(DateTimeFormatter formatter)方法进行格式化。
LocalDateTime localDateTime = LocalDateTime.now();
DateTimeFormatter dtf1 = DateTimeFormatter.ISO_LOCAL_DATE;
System.out.println(dtf1.format(localDateTime));
DateTimeFormatter dtf2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
System.out.println(dtf2.format(localDateTime));
DateTimeFormatter dtf3 = DateTimeFormatter.ofPattern("Gyyyy/MMM/dd HH:mm:ss");
System.out.println(dtf3.format(localDateTime));
System.out.println(localDateTime.format(dtf3));