JDK8日期类入门
关于jdk8的时间类的用法,网上有很多教程教你如何用,比如:
System.out.println(LocalDateTime.now());
可以获取当前的时间,
2020-12-06T18:02:39.215
但我想从另一个角度来思考这些时间类。
首先,我想明确一个观点:
JDK8中的日期类是什么?
我认为其本质就是对这个世界上时间的一种抽象封装
。
为什么这么说呢,耐心点看下去。
第一个问题,地球上的时间从哪来?
害。这不是屁话么,小学生都知道地球上的时间是通过地球绕太阳公转来的,以本初子午线为0时区,将地球划分为12个时区。比如北京就在东8区,也就是`UTC/GMT+08:00`
所以第一个概念就有了,那就是时区
,JDK8里称为Zone
,对应的用来求指定时区的类是ZonedDateTime
,以下为代码示例:
import java.time.ZoneId;
import java.time.ZonedDateTime;
/**
* @author Alin
* @desc //TODO
* @date 2020/12/6
*/
public class TestLocalDateTime {
public static void main(String[] args) {
final ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);
final ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime.toString());
}
}
从结果可以看出,不同时区对应的时间不同,东京比上海快了一个小时:
2020-12-06T19:02:59.765+08:00[Asia/Shanghai]
2020-12-06T20:02:59.766+09:00[Asia/Tokyo]
当然,这个世界的时间设计不可能只有时区,以东8区举例,
此时区内该如何计算时间呢?
JDK8提供了几种方式,比如:
- LocalDateTime
- LocalDate
- Instant
代码示例:
public class TestLocalDateTime {
@Test
void test2(){
System.out.println(LocalDateTime.now());
System.out.println(LocalDate.now());
final Instant now = Instant.now();
System.out.println(now);
System.out.println(now.toEpochMilli());
System.out.println(System.currentTimeMillis());
System.out.println(LocalTime.now());
}
}
2020-12-06T19:36:35.323
2020-12-06
2020-12-06T11:36:35.323Z
1607254595323
1607254595328
19:36:35.328
从结果看,LocalDateTime可以获得当前时区的年月日时分秒,LocalDate则是年月日,Instant则可以获取自1970-01-01T00:00:00Z到现在的毫秒数,LocalTime就是时分秒了,注意,Instant获取的结果是不考虑时区
的,所以差了8个小时,其他是指系统默认时区。
从命名上看的也很明显,Local指本地(本时区、系统默认时区),Date指日期,Time指时间。
按照逻辑推断,其中必然有转换关系
,知道了年月日时分秒,那肯定能单独转换为年月日或者时分秒吧,的确JDK8也做了封装:
public class TestLocalDateTime {
@Test
void test3(){
final LocalDateTime localDateTime = LocalDateTime.now();
final LocalDate localDate = LocalDate.now();
final LocalTime localTime = LocalTime.now();
final Instant instant = Instant.now();
final LocalDate toLocalDate = localDateTime.toLocalDate();
final LocalTime toLocalTime = localDateTime.toLocalTime();
final long milli = localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli();
}
}
我们这个世界还需要哪些时间单位呢?
比如,年、月、周、日,对应的类如Year
、Month
、DayOfWeek
、MonthDay
,被设计用来增强代码的可读性和可靠性。
时间也是有范围的,比如几个小时/持续了几秒/天/月等:
Duration
表示以秒和纳秒为基准的时长。例如,“10.3秒”。
Period
表示以年、月、日衡量的时长。例如,“1年5个月零13天”。
另外,该如何格式化日期呢,这个JDk8也有封装,最常用的DateTimeFormatter
就可以做到:
public class TestLocalDateTime {
@Test
void test4(){
final LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
}
}
还有一个很方便的工具类TemporalAdjusters
,代码如下:
public class TestLocalDateTime {
@Test
void test5(){
final LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
final LocalDateTime with = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(with);
}
}
可以方便的计算诸如本月的最后一天等等问题,具体可自查api:
2020-12-06T20:07:26.181
2020-12-31T20:07:26.181