早期,Java 对时间和日期的使用往往重度依赖 java.util.Date和java.util.Calendar。 可惜的是,这2个api 本身不够健壮,有类似线程不安全等诸多问题,于是乎2000年左右,市面上出现了很多用于处理时间类的框架,如Joda-Time。 在Java 8 时代 官方为JDK开发新的时间/日期API的进程:JSR-310,启动了。于是就出现了新一套健壮的API。
Java 8 中 新的API 包括了 5个包
java.time
java.time.chrono
java.time.format
java.time.temporal
java.time.zone
java.time 是基础包,里面包含了 时间 日期的 基础类 如 LocalDate, LocalTime等
java.time.chrono 有点像linux 的守护进程 chronyd 用来访问不同的时间服务器。
java.time.format 顾名思义用来格式化和转换日期时间
java.time.temporal 可能也想不出好名字吧,里面都是些底层扩展类
java.time.zone 用来对各时区的支持
LocalDate 是新API 中 最基础也是最重要的类, 它是一个 不可变的类(final 修饰),本地日期只是一个术语,用来表示一个具体日期,不同地区的日期可能不同 故采用 local 这个术语,其实它是时区无关的,这个类没有包含任何时区信息,就简单的认为一个日期即可。
日期的创建 采用了工厂方法的模式,所有的创建方法都是私有的,常用的是调用对外开放的方法of 来生成一个 日期实例
LocalDate localDate = LocalDate.of(int year, Month month, int dayOfMonth); LocalDate localDate = LocalDate.of(int year, int month, int dayOfMonth);
其中 Month 是一个枚举类。
例子:
LocalDate localDate = LocalDate.of(2016,Month.FEBRUARY,18);
LocalDate 的toString方法 默认返回的日期格式 采用 ISO-8601标准日期 即 YYYY-MM-DD
System.out.println(localDate); //2016-02-18
LocalDate 还提供了其他很多常用方法来获得日期的相关值
System.out.println(localDate.getMonth()); // Month FEBRUARY 当前月 System.out.println(localDate.getMonthValue()); // int 1 当前月的数值 System.out.println(localDate.getDayOfMonth()); // int 18 当前月第X天 System.out.println(localDate.getDayOfWeek()); // DayOfWeek Monday 当前周的天 System.out.println(localDate.getDayOfYear()); // int 49 当前年的第X天 System.out.println(localDate.getYear()); // int 2016 当前年 System.out.println(localDate.lengthOfYear()); // int 366 当前年共有多少天 System.out.println(localDate.lengthOfMonth()); // int 29 当前月共有多少天
LocalDate 是一个不可变的类,它的每一次操作 都会伴随生成一个新类
System..println(localDate.withYear())System..println(localDate.plusMonths())System..println(localDate.minusDays())
LocalDate 也提供了一些属性判断的功能
System.out.println( localDate.isLeapYear()); // true (是闰年)
LocalTime 的用法和 LocalDate 类似同样与与时区无关, 它的默认格式也是采用 ISO-8601 格式为 HH:mm:ss
LocalTime localTime = LocalTime.of(int hour, int minute, int second); LocalTime localTime = LocalTime.of(int hour, int minute, int second, int nanoOfSecond) LocalTime localTime = LocalTime.of(int hour, int minute);
例子:
LocalTime localTime = LocalTime.of(17,10,58);
LocalDateTime类是LocalDate和LocalTime的简单组合。它表示一个跟时区无关的日期和时间。
LocalDateTime的API 与 LocalDate和LocalTime 非常类似 可以非常灵魂的组件自己的时间日期。
-------------------------------------Example TBD------------------------------
时间点是表示时间的某时某刻的,相对的它是时间线上的一点,在建模的时候有用,在java 8中
java.time包通过值类型Instant提供机器视图。Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。
Instant start = Instant.()Instant end = Instant.()System..println(start)System..println(end)
java.time还为时间长度额外提供了两个值类型。
Duration表示以秒和纳秒为基准的时长。例如,“23.6秒”。
Period表示以年、月、日衡量的时长。例如,“3年2个月零6天”。
period 表示的是一段时间 以 日月年为单位. 在日期的操作中 可以作为参数 来作为日期的加减运算
Period period = Period.()System..println(period)System..println(period.getDays())System..println(period.getMonths())System..println(period.getYears())
Duration表示的是一段时间 以 分十秒为单位. 在时间的操作中 可以作为参数 来作为时间的加减运算
Duration duration = Duration.()System..println(duration)System..println(duration.getSeconds())
--------------------------TBD-----------------------
Java 8 中 java.time.format 中 围绕 DateTimeFormatter 构建了时间的解析与转换。Java 8 默认的时间显示格式是
ISO 8601标准格式。
最简单的方法就是 调用 时间日期 自己的 formate(DateTimeFormatter.TYPE)方法, 采用 Java 8 提供的一些ISO 格式 进行格式化输出。
LocalDate date = LocalDate.of(2020, Month.JANUARY, 20); LocalTime time = LocalTime.of(11, 12, 34); LocalDateTime dateTime = LocalDateTime.of(date, time); System.out.println(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); //2020-01-20 System.out.println(dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); //2020-01-20T11:12:34 System.out.println(time.format(DateTimeFormatter.ISO_LOCAL_TIME)); //11:12:34 System.out.println(date.format(DateTimeFormatter.ISO_DATE)); //2020-01-20 System.out.println(dateTime.format(DateTimeFormatter.ISO_DATE_TIME)); //2020-01-20T11:12:34 System.out.println(time.format(DateTimeFormatter.ISO_TIME)); //11:12:34
采用 DateTimeFormatter.format() 方法进行格式化输出
首先需要 实例化一个DateTimeFormatter 调用 .ofLocalizedDate ..... 需要注意的是,转化器与日期时间对象要一一对应切不可 LocalDate对象 用DateTimeFormatter.ofLocalDateTime. 这样会抛出UnsupportedTemporalyException.
DateTimeFormatter shortDateTime = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM); DateTimeFormatter shortDateTime = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); DateTimeFormatter shortDateTime = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
其中FormatSyle 是一个枚举类 它包括了 FULL,LONG,MEDUM,SHORT 等诸多格式,主要根据要求来。
DateTimeFormatter shortDateTime = DateTimeFormatter.(FormatStyle.)System..println(shortDateTime.format(dateTime))
除了之前介绍的一些预定义格式以外,还可以输出一些自定义的时间格式采用 字符串匹配模式
DateTimeFormatter f = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm");
MMMM 对应 月份 M outputs 1, MM outputs 01, MMM outputs Jan, and MMMM outputs January.
dd,DD 对应天数
YYYY,YY,yyyy,yy 对应 年份
HH 对应 24小时制的 小时
hh 对应 12小时制的 小时
mm 对应 分钟
ss 对应 秒
SS 对应 毫秒
此外 还可以包括 类似 / , : - 等分隔符
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm"); System.out.println(dateTime.format(f1)); // January 20, 2020, 01:12 DateTimeFormatter f2 = DateTimeFormatter.ofPattern("MM dd, yyyy, hh:mm"); System.out.println(dateTime.format(f2)); // 01 20, 2020, 01:12 DateTimeFormatter f3 = DateTimeFormatter.ofPattern("MMMM DD, YY, HH:mm"); System.out.println(dateTime.format(f3)); // January 20, 2020, 13:12 DateTimeFormatter f4 = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm"); System.out.println(dateTime.format(f4)); // January 20, 2020, 01:12 DateTimeFormatter f5 = DateTimeFormatter.ofPattern("MMMM dd, yy, hh:mm:ss"); System.out.println(dateTime.format(f5)); // January 20, 2020, 01:12:34 DateTimeFormatter f6 = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm:ss:SS"); System.out.println(dateTime.format(f6)); // January 20, 2020, 01:12:00
时间的解析和 DateTimeFormatter中 ofPatter 结合使用 配合要解析的字符串 对应好 时间位 就可以了。
DateTimeFormatter f = DateTimeFormatter.()LocalDate date = LocalDate.(f)LocalTime time = LocalTime.()System..println(date)System..println(time)