JDK8 Instant类的使用和LocalDate,LocalTime 和 LocalDateTime的介绍。
简介
在Java 8中又为我们提供了新的日期类。它可以帮我们更精确的保存记录时间。
本文章主要介绍的就是Instant,LocalDate,LocalTime 和 LocalDateTime 这几个类。
UTC
世界标准时间“Coordinated Universal Time”,因为地区的差异,所以有时差。比如:
北京的白天,纽约却是夜晚;
两个人都是8点50出生的,但一个是在法国出生的,一个是在韩国出生的,看上去是一样大,但法国比韩国慢7个小时;
我们想要把两个时间作比较,就需要先转换为世界标准时间再作比较。
协调世界时区会使用“Z”来表示。 北京时间是东八区时间。
Instant的使用
它是精确到纳秒的(而不是象旧版本的Date精确到毫秒)。如果使用纳秒去表示一个时间则原来使用一位Long类型是不够的,需要占用更多一点的存储空间,实际上其内部是由两个Long字段组成,第一个部分保存的是自标准Java计算时代(就是1970年1月1日开始)到现在的秒数,第二部分保存的是纳秒数(永远不会超过999,999,999)。
我们看下一个具体的例子:
常用方法
now()
获取当前时间
//获得当前时间
Instant instant = Instant.now(); //该方法返回一个记录当前格林威治标准时间的Instant对象的引用。
System.out.println(instant);
结果为:
2020-07-25T14:31:48.146Z //精确到了纳秒
toEpochMilli():
获取1970年1月1日至所记录时间的的毫秒数,类似于Date.getTime()。
long l = instant.toEpochMilli();
System.out.println(l); // 1593222457253
ofEpochMilli(ZoneOffest offest):
将Date对象、日期字符串转换为Instant对象
//将java.util.Date转换为Instant
Instant instant = Instant.ofEpochMilli(new Date().getTime());
//从字符串类型中创建Instant类型的时间
instant = Instant.parse("2020-07-23T11:45:37Z");
atOffset(ZoneOffest offest):
北京时间是东八区时间。因此需要对Instant实例化对象进行偏移量的设置。
通过调用ZoneOffest类的静态方法ofHours(int n),传入一个数值即可设置偏移的小时量。该方法返回一个OffsetDateTime对象的引用。
// 按时区设置偏移量
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));// 设置偏移量为8
System.out.println(offsetDateTime);
结果:
2020-07-27T09:47:37.253+08:00
plus(TemporalAmount amountToAdd) 加时间
instant.plus(Duration.ofHours(2).plusMinutes(3)); //在先在时间的基础上加2小时3分钟
minus(TemporalAmount amountToSubtract) 减时间
//计算5天前的时间
instant.minus(5, ChronoUnit.DAYS); // Option 1 方法1
instant.minus(Duration.ofDays(5)); // Option 2 方法2
//计算两个Instant之间的分钟数
long diffAsMinutes = instant.periodUntil(instant1, ChronoUnit.MINUTES); // 方法1
long diffAsMinutes = ChronoUnit.MINUTES.between(instant, instant1); // 方法2
Duration
字面意思是持续时间,表示一天时间,一小时,一分钟。
//设置指定单位的持续时间
Duration durationDays = Duration.ofDays(1);//天
Duration durationHours = Duration.ofHours(1);//小时
Duration durationMinutes = Duration.ofMinutes(1);//分
Duration durationSeconds = Duration.ofSeconds(1);//秒
Duration durationMillis = Duration.ofMillis(1);//毫秒
//将设置的单位时间转换成小时,分钟,秒,纳秒
Duration duration = Duration.ofDays(1);//设置一天时间
long timeHours = duration.toHours();//小时 24
long timeMinutes = duration.toMinutes();//分钟 1440
long timeMillis = duration.toMillis();//毫秒 86400000
long timeNanos = duration.toNanos();//纳秒 86400000000000
String timeString = duration.toString(); //此持续时间的字符串表示形式,使用基于ISO-8601秒*的表示形式,例如 PT8H6M12.345S
//求两个日期差值
Duration duration = Duration.between(start, end);
LocalDate和LocalTime
LocalDate 表示不带时区的日期,比如 1-1-2000。LocalTime 表示不带时区的时间,比如 04:44:50.12,和之前提到的 Instant 类是从1970年计算偏移量不同,这两个类的输出是人们习惯阅读的日期和时间。有很多种方法去获得 LocalTime 和 LocalDate 的实例,如:
LocalDate localDate = LocalDate.now();
localDate = LocalDate.ofYearDay(2005, 86); // 获得2005年的第86天 (27-Mar-2005)
localDate = LocalDate.of(2013, Month.AUGUST, 10); //2013年8月10日
LocalTime localTime = LocalTime.of(22, 33); //10:33 PM
localTime = LocalTime.now();
localTime = LocalTime.ofSecondOfDay(4503); // 返回一天中的第4503秒 (1:15:30 AM)
LocalDate 和 LocalTime 和 Instant 一样遵守同样的线程规定―― 如它们的实例子都是不可变的。LocalDate 和 LocalTime 和 Instant 有同样的计算和比较方法(其中有些方法是在 java.time.temporal.Temporal接口中定义的,并且上面这些类都实现了这些方法):
LocalDate localDate1 = localDate.plus(5, ChronoUnit.HOURS);
localDate.isBefore(localDate1);
LocalDateTime
它是LocalDate和LocalTime的组合体,表示的是不带时区的 日期及时间。
LocalDateTime localDateTime = LocalDateTime.now();
//当前时间加上25小时3分钟
LocalDateTime inTheFuture = localDateTime.plusHours(25).plusMinutes(3);
// 同样也可以用在localTime和localDate中
System.out.println(localDateTime.toLocalTime().plusHours(25).plusMinutes(3));
System.out.println(localDateTime.toLocalDate().plusMonths(2));
// 也可以使用实现TemportalAmount接口的Duration类和Period类
System.out.println(localDateTime.toLocalTime().plus(Duration.ofHours(25).plusMinutes(3)));
System.out.println(localDateTime.toLocalDate().plus(Period.ofMonths(2)));
Instant 和 LocalDateTime的区别
Instant :
表示来自时代的偏移量(01-01-1970),表示时间线上的某个瞬间。
同一时刻在地球上的两个不同地方创建的物体将具有完全相同的价值。
LocalDateTime:
LocalDateTime是一个不可变的日期时间对象。 如2020-07-23T11:21:30
如果没有附加信息(如偏移或时区),它不能代表时间线上的瞬间。
字符串与LocalDateTime、LocalDate、Instant、Date之间相互转换
//设置时区偏移量 中国就是8个小时
public static final ZoneOffset ZONE_CHINA = ZoneOffset.ofHours(8);
//T代表可替换的任意字符,SSS指的是毫秒,Z代表的时区。--"2020/12/18T10:00:51.268+0800"
public static final DateTimeFormatter FORMATTE_Z = DateTimeFormatter.ofPattern("yyyy/MM/dd'T'HH:mm:ss.SSSZ");
//没有时区 --"2020-12-18T10:00:51.268"
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
public static final DateTimeFormatter FORMATTER2 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH-mm-ss.SSS");
//设置时区
public static final DateTimeFormatter FORMATTER_CHINA = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.withZone(ZoneId.systemDefault())
.withLocale(Locale.CHINA );
public static void main(String[] args) {
//字符串转LocalDateTime
//转换的格式一定是匹配的,否则会报错
//默认的转换格式 yyyy-MM-dd'T'HH:mm:ss.SSS
String str1 = "2020-12-18T10:00:51.268";
LocalDateTime parse1 = LocalDateTime.parse(str1);
System.out.println(parse1);//2020-12-18T10:00:51.268
//自定义格式转换
String str2 = "2020/12/18T10:00:51.268+0800";
LocalDateTime parse2 = LocalDateTime.parse(str2, FORMATTE_Z);
System.out.println(parse2);//2020-12-18T10:00:51.268
String str3 = "2020-12-18 10:00:51.268";
LocalDateTime parse3 = LocalDateTime.parse(str3, FORMATTER);
System.out.println(parse3);//2020-12-18T10:00:51.268
//LocalDateTime转字符串
String format = parse1.format(DateTimeFormatter.ofPattern("yyyy=MM==dd HH+mm+ss.SSS"));
System.out.println(format);
//字符串转LocalDate
String str4 = "2020-12-18";
LocalDate parse4 = LocalDate.parse(str4);
String str5 = "2020/12/18";
LocalDate parse5 = LocalDate.parse(str5, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
System.out.println(parse4);//2020-12-18
System.out.println(parse5);//2020-12-18
String format2 = parse4.format(DateTimeFormatter.ofPattern("yyyy=MM==dd"));
System.out.println(format2);
//字符串转Instant
String str6 = "2007-12-03T10:15:30.145Z";
Instant parse6 = Instant.parse(str6);
System.out.println(parse6);
String format1 = FORMATTER_CHINA.format(parse6);
System.out.println(format1);//2007-12-03T10:15:30.145Z
//Instant转LocalDateTime Instant实例 时区偏移量
LocalDateTime dateTime = LocalDateTime.ofInstant(parse6, ZONE_CHINA);
//Instant转LocalDate
LocalDate date = LocalDate.ofInstant(parse6,ZONE_CHINA);
//LocalDateTime转LocalDate
LocalDate localDate = dateTime.toLocalDate();
//Date
//public static Date from(Instant instant)
//public Instant toInstant()
//Instant转Instant
Date from = Date.from(parse6);
System.out.println(from);
//LocalDateTime和LocalDate可以先转换成Instant,再转换成Date对象
//Date对象可以先转换成Instant在转换到其他时间对象
}