Java关于LocalDate、LocalTime、LocalDateTime类的详细讲解_金士曼的博客-CSDN博客_local时间类
Java关于LocalDate、LocalTime、LocalDateTime类的详细讲解
Java关于日期和时间相关API必须明白的方法和类(JDK8之后部分)
文章目录
PS:Java中Data类的使用、JDK8之前日期时间API的讲解
新日期时间API出现的背景
- JDK 1.0中包含了 一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用 了。而Calendar并不比Date好多少。它们面临的问题是:
- 可变性:像日期和时间这样的类应该是不可变的。 (比如片首的超链接文章,最后的日历类java.util.Calendar,应该返回一个新的对象,但是因为有可变性,却是对原本的时间进行了改变)
- 偏移性:Date中的年份是从1900开始的,而月份都从0开始。
举例:这里返回的因为有偏移量,所以输入的并不是我们需要的,idea也提醒说过时了(过时不等于不能用)
Date date = new Date(2019, 10, 1);
System.out.println(date);//Sat Nov 01 00:00:00 CST 3919
12
- 格式化:格式化只对Date有用,Calendar则不行。
- 此外,它们也不是线程安全的;不能处理闰秒等。
新时间日期API
- 第三次引入的API是成功的,并且Java 8中引入的java.time API 已经纠正了 过去的缺陷,将来很长一段时间内它都会为我们服务。
- Java 8 吸收了 Joda-Time 的精华,以一个新的开始为 Java 创建优秀的 API。 新的 java.time 中包含了所有关于本地日期(LocalDate)、本地时间 (LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime) 和持续时间(Duration)的类。历史悠久的 Date 类新增了 toInstant() 方法, 用于把 Date 转换成新的表示形式。这些新增的本地化时间日期 API 大大简 化了日期时间和本地化的管理。
- 新时间日期API有:
- java.time – 包含值对象的基础包
- java.time.chrono – 提供对不同的日历系统的访问
- java.time.format – 格式化和解析时间和日期
- java.time.temporal – 包括底层框架和扩展特性
- java.time.zone – 包含时区支持的类
⭕️说明:大多数开发者只会用到基础包和format包,也可能会用到temporal包。因此,尽 管有68个新的公开类型,大多数开发者,大概将只会用到其中的三分之一,而且在这之前就以及存在joda-Time这个jar包,假如在公司里用的是jdk8之前,就得引用这个jar包,JDK1.8的API重写了日期库,引入的java.time包,其实也是借鉴了Joda-Time)
LocalDate、LocalTime、LocalDateTime 类
- LocalDate、LocalTime、LocalDateTime 类是其中较重要的几个类,它们的实例 是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。 它们提供了简单的本地日期或时间,并不包含当前的时间信息,也不包含与时区 相关的信息。 *
- LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。
- LocalTime表示一个时间,而不是日期。
- LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。
注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示 法,也就是公历
⭕️:LocalDate:本地日期
⭕️:LocalTime:本地时间
⭕️:LocalDateTime:本地的日期时间都有
- 静态方法部分:
方法一:.now():静态方法,根据当前时间创建对象/指定时区的对象
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate);//2022-10-10(日期)
System.out.println(localTime);//08:36:29.174(时间)
System.out.println(localDateTime);//2022-10-10T08:36:29.174(日期+时间)
123456
方法二:of():静态方法,根据指定日期/时间创建对象
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 10, 6, 13, 12, 43);
System.out.println(localDateTime1);//2020-10-06T13:12:43
12
- get方法部分(用LocalDateTime测试,里面含有年月日时分秒)
方法一:getDayOfMonth()/getDayOfYear()/getDayOfWeek() : 获得月份天数(1-31) /获得年份天数(1-366)
LocalDateTime localDateTime3 = LocalDateTime.now();
System.out.println(localDateTime3.getDayOfMonth());//10
System.out.println(localDateTime3.getDayOfYear());//283
System.out.println(localDateTime3.getDayOfWeek());//MONDAY
1234
方法二:getMonth()/getMonthValue() :获得月份, 返回一个 Month 枚举值/(阿拉伯数字) getYear()获取年份
LocalDateTime localDateTime3 = LocalDateTime.now();
System.out.println(localDateTime3.getMonth());//OCTOBER
System.out.println(localDateTime3.getMonthValue());//10
System.out.println(localDateTime3.getYear());//2022
1234
方法三:getHour()/getMinute()/getSecond() :获得当前对象对应的小时、分钟、秒
LocalDateTime localDateTime3 = LocalDateTime.now();
System.out.println(localDateTime3.getHour());//8
System.out.println(localDateTime3.getMinute());//54
System.out.println(localDateTime3.getSecond());//18
1234
- **设置部分:**withDayOfMonth()/withDayOfYear()/ withMonth()/withYear() :将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象(体现的是不可变性)(只举例部分代码,主要说明不可变性)
System.out.println(localDateTime3);//2022-10-10T09:01:38.958(执行方法前)
LocalDateTime localDateTime2 = localDateTime3.withDayOfMonth(22);//修改当月的第几天
System.out.println(localDateTime2);//2022-10-22T09:01:38.958(新数据)
System.out.println(localDateTime3);//2022-10-10T09:01:38.958(执行方法后原数据并没有改变)
1234
- 添加时间操作:plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours():向当前对象添加几天、几周、几个月、几年、几小时(代码举例部分)
LocalDate localDate2 = localDate.plusDays(3);
System.out.println(localDate);//2022-10-10
System.out.println(localDate2);//2022-10-13
123
- 减去时间操作:minusMonths() / minusWeeks()/ minusDays()/minusYears()/minusHours():从当前对象减去几月、几周、几天、几年、几小时(代码举例部分)
LocalDate localDate2 = localDate.minusDays(3);
System.out.println(localDate);//2022-10-10
System.out.println(localDate2);//2022-10-07
123
瞬时:Instant
- Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。
- 在处理时间和日期的时候,我们通常会想到年,月,日,时,分,秒。然而,这只是 时间的一个模型,是面向人类的。第二种通用模型是面向机器的,或者说是连 续的。在此模型中,时间线中的一个点表示为一个很大的数,这有利于计算机 处理。在UNIX中,这个数从1970年开始,以秒为的单位;同样的,在Java中, 也是从1970年开始,但以毫秒为单位。
- java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间 单位。Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。 概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒 数。因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。
- (1 ns = 10-9 s) 1秒 = 1000毫秒 =106微秒=109纳秒
时间戳:是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01 日08时00分00秒)起至现在的总秒数。
- now():静态方法,返回默认UTC时区的Instant类的对象(相当于获取本初子午线的时间点,与我国小8小时),需要用atOffset方法添加偏移量
//(算出来的结果不是我们中国的时间,是本初子午线的时间,我们国家在东八区与之差8个小时)
System.out.println(instant);//2022-10-10T01:48:58.692Z
OffsetDateTime oft1 = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println(oft1);//2022-10-10T09:48:58.692+08:00
1234
- 时间戳:toEpochMilli():返回1970-01-01 00:00:00到当前时间的毫秒数,即为时间戳(类似Date类的getTime()方法)
long l = instant.toEpochMilli();
System.out.println(l);//1970-01-01 00:00:00到当前时间的毫秒数
12
- ofEpochMilli(long epochMilli) :通过给定的毫秒数,获取Instant实例(类似Date(long millis))
Instant instant1 = Instant.ofEpochMilli(12312412);
System.out.println(instant1);
12
格式化与解析日期或时间
⭕️:java.time.format.DateTimeFormatter 类:格式化或解析日期、时间,类似于首文推荐文章中的SimpleDateFormat
格式化和解析:日期<——>字符串
该类提供了三种格式化方法:(常用自定义方式)
- 预定义的标准格式。如: ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
- 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
- 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
方 法 | 描 述 |
---|---|
ofPattern(String pattern) | 静态方法 , 返 回 一 个 指 定 字 符 串 格 式 的 DateTimeFormatter |
format(TemporalAccessor t) | 格式化一个日期、时间,返回字符串 |
parse(CharSequence text) | 将指定格式的字符序列解析为一个日期、时间 |
- 格式化方式一:预定义的标准格式
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE;//选择格式:ISO_DATE
LocalDate localDate1 = LocalDate.now();//实例化对应格式的对象(这里选择的ISO_DATE,所以用LocalDate)
String format = dtf.format(localDate1);//格式化返回字符串
System.out.println(format);//2022-10-10
1234
对应的解析:(只能解析当时实例化DateTimeFormatter类,格式化时选择的那个格式)
TemporalAccessor parse = dtf.parse("2022-10-10");//方式必须和dtf的那个格式化方式相同
System.out.println(parse.toString());//接口的方式呈现
12
- 格式化方式二:本地化相关的格式(FormatStyle.FULL/FormatStyle.LONG/FormatStyle.SHORT等等)
DateTimeFormatter dtf2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);//选择格式之一FormatStyle.FULL
//不同格式只是最后结果的格式不一样,这里不细究
LocalDate localDate3 = LocalDate.now();
String format1 = dtf2.format(localDate3);//格式化返回字符串
System.out.println(format1);//2022年10月10日
12345
对应的解析:(一样调用parse()方法,格式也只能选择实例化dtf2当时的格式)
TemporalAccessor parse1 = dtf2.parse(format1);接口的方式呈现
TemporalAccessor parse2 = dtf2.parse("2021年9月8日");
System.out.println(parse1);//{},ISO resolved to 2022-10-10
System.out.println(parse2);//{},ISO resolved to 2021-09-08
1234
- 格式化方式三(常用):
DateTimeFormatter dtf3 = DateTimeFormatter.ofPattern("yy-MM-dd hh:mm:ss");
LocalDateTime ldt1 = LocalDateTime.now();
String format2 = dtf3.format(ldt1);
System.out.println(format2);//22-10-10 01:15:06
1234
对应的解析:(一样调用parse()方法,格式也只能选择实例化dtf3当时的格式)
TemporalAccessor parse3 = dtf3.parse(format2);
System.out.println(parse3);//
12
总结:(重点)
格式化步骤
- 实例化DateTimeFormatter,根据不同方法选择对应的需要的格式(DateTimeFormatter.ofPattern(自定义)/ofLocalizedDate(本地化相关的格式)ISO_DATE(预定义的标准格式)等等)
- 根据当前的时间,用now()方法创建需要的对象(LocalDate、LocalTime、LocalDateTime )
- 用实例化DateTimeFormatter类后的对象调用format方法去格式化刚刚用now方法创建的对象,返回字符串
- 这时候已经完成格式化完成并且得到了返回的字符串,按需要输出或者进行其他操作就行
解析步骤
- 用实例化DateTimeFormatter类后的对象调用parse方法,并且需要和当时实例化时候格式一样的字符串,并且以接口的方式返回了一个时间(因为不确定选择了什么格式)
- 这时候已经完成了解析,输出或者进行其他操作即可