文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

java8之LocalDate的使用、LocalDate格式化问题

2023-05-17 14:46

关注

前言

Java 8里面添加了许多的新特性,其中一个最常见也是最实用的便是日期处理的类——LocalDate。

新增的日期类主要有三种:

LocalDate:默认返回一个日期格式为yyyy-MM-dd格式的日期

一:创建LocalDate

方法说明
static LocalDate now()获取默认时区的当前日期,默认返回格式yyyy-MM-dd
static LocalDate now(Clock clock)从指定时钟获取当前日期
static LocalDate now(ZoneId zone)获取指定时区的当前日期
static LocalDate of(int year, int month, int dayOfMonth)根据指定的年、月、日获取LocalDate 实例
static LocalDate of(int year, Month month, int dayOfMonth)根据指定的年、月、日获取LocalDate 实例
static LocalDate ofYearDay(int year,int dayOfYear)根据指定的年,年中的第xx天获取LocalDate实例
static LocalDate ofEpochDay(long epochDay)从1970-01-01开始获取指定天数的LocalDate实例
static LocalDate parse(CharSequence text)将字符串转换为LocalDate,字符串的格式必须为yyyy-MM-dd 10位长度的日期格式,否则会报错
static LocalDate parse(CharSequence text, DateTimeFormatter formatter)将text字符串转换为formatter格式,text的格式必须与formatter格式一致,如text为yyyyMMdd格式,则formatter也应该为yyyyMMdd格式,否则会报错

1、now()

从默认时区的系统时钟中获取当前日期。默认输出格式为yyyy-MM-dd

LocalDate localDate = LocalDate.now();
System.out.println(localDate);

2021-11-29

2、now(Clock clock)

从指定时钟获取当前日期。

LocalDate l = LocalDate.now(Clock.systemDefaultZone());
System.out.println(l);

System.out.println(Clock.systemDefaultZone());//方法返回带有系统默认时区的Clock实例。
System.out.println(Clock.systemUTC());//此方法返回带有UTC时区的Clock实例。
2021-11-29

SystemClock[Asia/Shanghai]
SystemClock[Z]

3、now(ZoneId zone)

从指定时区的系统时钟中获取当前日期。

LocalDate l = LocalDate.now(ZoneId.of("UTC+1"));
System.out.println(l);

2021-11-29

时区是用ZoneId类表示的,你可以使用ZoneId.now()或ZoneId.of(“xxx”)来实例化:

ZoneId zoneId = ZoneId.of("UTC+1");

传给of()方法的参数是时区的ID,如“UTC+1”指距离UTC(格林威治时间)有一小时的时差,你可以使用你想要的时差来表示ZoneId(如+1与-5等等)

你也可以使用另一种方式表示zone id,即使用地区名字,也是可以的:

ZoneId zoneId2 = ZoneId.of("Europe/Copenhagen");
ZoneId zoneId3 = ZoneId.of("Europe/Paris");

4、of(int year, int month, int dayOfMonth)

从年、月和日获取LocalDate实例

LocalDate l = LocalDate.of(2021, 11, 29);
System.out.println(l);

2021-11-29

5、ofYearDay(int year,int dayOfYear)

从指定年的指定天获取LocalDate实例

//获取2021年第230天的日期
LocalDate l = LocalDate.ofYearDay(2021, 230);
System.out.println(l);

2021-08-18

6、ofEpochDay(long epochDay)

从1970-01-01开始获取指定天数的LocalDate实例

LocalDate l = LocalDate.ofEpochDay(0);//1970-01-01
LocalDate l1 = LocalDate.ofEpochDay(-10);//1969-12-22
LocalDate l2 = LocalDate.ofEpochDay(10);//1970-01-11

7、parse(CharSequence text)

将字符串转换为LocalDate,字符串的格式必须为yyyy-MM-dd 10位长度的日期格式,否则会报错,字符串必须是一个合法的日期,否则会报错

LocalDate l = LocalDate.parse("2021-01-29");
System.out.println(l); //2021-01-29

错误示例:

//日期格式非yyyy-MM-dd
LocalDate l = LocalDate.parse("2021-1-29");
//日期格式非yyyy-MM-dd
LocalDate l = LocalDate.parse("2021/01/29");
//字符串不是一个合法的日期,2月没有30号
LocalDate l = LocalDate.parse("2021-02-30");

若parse(CharSequence text)中传入的格式非yyyy-MM-dd或不合法,会抛出异常,且长度需要是10位

Exception in thread "main" java.time.format.DateTimeParseException: Text '2021/11/29' could not be parsed at index 4
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
    at java.base/java.time.LocalDate.parse(LocalDate.java:428)
    at java.base/java.time.LocalDate.parse(LocalDate.java:413)
    at com.aexpec.mic.merchant.controller.Test.main(Test.java:19)

8、parse(CharSequence text, DateTimeFormatter formatter)

将text字符串转换为formatter格式,text的格式必须与formatter格式一致,如text为yyyyMMdd格式,则formatter也应该为yyyyMMdd格式,否则会报错

LocalDate l = LocalDate.parse("2021-11-29", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDate localDate1 = LocalDate.parse("20211129", DateTimeFormatter.ofPattern("yyyyMMdd"));
System.out.println(l);
System.out.println(localDate1);

2021-11-29

2021-11-29

错误示例:

//错误示例:text与formatter格式不一致,会抛出异常
LocalDate l = LocalDate.parse("2021-11-29", DateTimeFormatter.ofPattern("yyyyMMdd"));
LocalDate localDate1 = LocalDate.parse("20211129", DateTimeFormatter.ofPattern("yyyy-MM-dd"));

二:LocalDate日期比较

方法说明
boolean isBefore(ChronoLocalDate other)检查日期是否在指定日期之前
boolean isAfter(ChronoLocalDate other)检查日期是否在指定日期之后
boolean isEqual(ChronoLocalDate other)比较日期是否相同
int compareTo(ChronoLocalDate other)日期比较localDateA.compareTo(localDateB),若相等返回0;若A>B,返回1 ;若A<B返回-1

1、boolean isBefore(ChronoLocalDate other)

用于检查此LocalDate值是否在给定的ChronoLocalDate(other)之前

LocalDate l = LocalDate.parse("2021-11-29");
System.out.println(l.isBefore(LocalDate.parse("2021-11-28"))); //false
System.out.println(l.isBefore(LocalDate.parse("2021-11-30"))); //true

2、boolean isAfter(ChronoLocalDate other)

用于检查此LocalDate值是否在给定的ChronoLocalDate(other)之后

LocalDate l = LocalDate.parse("2021-11-29");
System.out.println(l.isAfter(LocalDate.parse("2021-11-28"))); //true
System.out.println(l.isAfter(LocalDate.parse("2021-11-30"))); //false

3、boolean isEqual(ChronoLocalDate other)

用于检查此LocalDate值是否与给定的ChronoLocalDate(other)相等

LocalDate l = LocalDate.parse("2021-11-29");
System.out.println(l.isEqual(LocalDate.parse("2021-11-28"))); //false
System.out.println(l.isEqual(LocalDate.parse("2021-11-30"))); //false
System.out.println(l.isEqual(l)); //true

4、int compareTo(ChronoLocalDate other)

比较两个日期A.compareTo(B),若日期相同则返回0;

LocalDate l = LocalDate.parse("2021-11-29");
System.out.println(l.compareTo(LocalDate.parse("2021-11-28"))); //1
System.out.println(l.compareTo(LocalDate.parse("2021-11-30"))); //-1
System.out.println(l.compareTo(l)); //0

三:获取年、月、日

方法说明
int getYear()获取年份
Month getMonth()使用月枚举类型获取月份
int getMonthValue()返回数字月份 1-12月
int getDayOfMonth()获取日期在该月是第几天
DayOfWeek getDayOfWeek()获取日期是星期几
int getDayOfYear()获取日期在该年是第几天
boolean isLeapYear()检查是否闰年
int lengthOfMonth()返回日期所在月份共有几天
int lengthOfYear()返回日期所在年份共有几天
long toEpochDay()返回当前日期距离1970年1月1日的天数
LocalDate localDate = LocalDate.now();
System.out.println(localDate); // 2021-11-29

System.out.println("年 : " + localDate.getYear()); // 2021
System.out.println("月(英文) : " + localDate.getMonth()); // NOVEMBER
System.out.println("月(数字英文): " + localDate.getMonth().getValue()); // 11
System.out.println("月(数字英文): " + localDate.getMonthValue()); // 11
System.out.println("本月第几天 : " + localDate.getDayOfMonth()); // 29
System.out.println("星期几(英文) : " + localDate.getDayOfWeek()); // MONDAY
System.out.println("星期几(数字英文) : " + localDate.getDayOfWeek().getValue()); // 1
System.out.println("本年的第几天 : " + localDate.getDayOfYear()); // 333
System.out.println("是否润年 : " + localDate.isLeapYear()); // false
System.out.println("本月天数 : " + localDate.lengthOfMonth()); // 30
System.out.println("本年天数 : " + localDate.lengthOfYear()); // 365

四:日期计算,加/减年、月、周、日

4.1、加/减年、月、周、日

方法说明
LocalDate plus(long amountToAdd, TemporalUnit unit)通用方法,可以通过unit参数控制增加天、周、月、年
LocalDate plusDays(long daysToAdd)返回增加了*天的LocalDate副本
LocalDate plusWeeks(long weeksToAdd)返回增加了*周的LocalDate副本
LocalDate plusMonths(long monthsToAdd)返回增加了*月的LocalDate副本
LocalDate plusYears(long yearsToAdd)返回增加了*年的LocalDate副本
LocalDate minus(long amountToAdd, TemporalUnit unit)通用方法,可以通过unit参数控制减少天、周、月、年
LocalDate minusDays(long daysToSubtract)返回减少了*天的LocalDate副本
LocalDate minusWeeks(long weeksToSubtract)返回减少了*周的LocalDate副本
LocalDate minusMonths(long monthsToSubtract)返回减少了*月的LocalDate副本
LocalDate minusYears(long yearsToSubtract)返回减少了*年的LocalDate副本
LocalDate localDate1 = LocalDate.now();
localDate1 = LocalDate.parse("2021-11-29");
System.out.println(localDate1); // 2021-11-29

//通用方法
System.out.println("增加 : " + localDate1.plus(1, ChronoUnit.DAYS));

System.out.println("增加天数 : " + localDate1.plusDays(1)); // 2021-11-30
System.out.println("增加周数 : " + localDate1.plusWeeks(1)); // 2021-12-06
System.out.println("增加月数 : " + localDate1.plusMonths(1)); // 2021-12-29
System.out.println("增加年数 : " + localDate1.plusYears(1)); // 2022-11-29

//通用方法
System.out.println("减少 : " + localDate1.minus(1, ChronoUnit.DAYS));

System.out.println("减少天数 : " + localDate1.minusDays(1)); // 2021-11-28
System.out.println("减少月数 : " + localDate1.minusMonths(1)); // 2021-10-29
System.out.println("减少周数 : " + localDate1.minusWeeks(1)); // 2021-11-22
System.out.println("减少年数 : " + localDate1.minusYears(1)); // 2020-11-29

以上方法返回的都是LocalDate实例的副本,即源对象localDate1变量的值不变

4.2、计算两个日期的间隔

方法一:计算两个日期相差的天数

LocalDate start = LocalDate.of(2020,2,28);
LocalDate end = LocalDate.of(2021,12,3);

System.out.println("两个时间之间的相差的天数: "+(end.toEpochDay()-start.toEpochDay())); //644

方法二::计算两个日期相差的天数、月数、年数

ChronoUnit也可以计算两个单元之间的天数、月数或年数。

我们使用ChronoUnit类的between() 方法来执行相同的操作:

LocalDate start = LocalDate.of(2020,2,28);
LocalDate end = LocalDate.of(2021,12,3);
long days= ChronoUnit.DAYS.between(start , end );
结果:644
long month= ChronoUnit.MONTHS.between(start , end );
结果21
long year= ChronoUnit.YEARS.between(start , end );
结果 1

方法三: 计算两个日期相差的年月日

此方法主要是计算两个日期相差的年月日,不能计算出具体相差了多少天


LocalDate start = LocalDate.of(2020,2,28);
LocalDate end = LocalDate.of(2021,12,3);
Period period = Period.between(start,end);
System.out.println("两个时间之间的差值  年:"+period.getYears()+",月:"+period.getMonths()+",日:"+period.getDays());
两个时间之间的差值  年:1,月:9,日:5

五:日期格式化

方法说明
String format(DateTimeFormatter formatter)使用特定格式化形式将LocalDate转为字符串
static LocalDate parse(CharSequence text)从文本字符串获取LocalDate实例,text必须是yyyy-MM-dd格式
static LocalDate parse(CharSequence text, DateTimeFormatter formatter)使用特定格式化形式从文本字符串获取LocalDate实例,text的格式必须与formatter格式一致,如text为yyyyMMdd格式,则formatter也应该为yyyyMMdd格式,否则会报错
LocalDate l = LocalDate.parse("2021-01-29");
System.out.println(l); //2021-01-29

LocalDate l1 = LocalDate.parse("2021-11-29", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(l1); //2021-11-29

LocalDate localDate1 = LocalDate.parse("20211129", DateTimeFormatter.ofPattern("yyyyMMdd"));
System.out.println(localDate1); //2021-11-29

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
System.out.println(l.format(dtf));// 2021-01-29 十位转八位 ==> 20210129

dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
System.out.println(l.format(dtf));// 2021-01-29  ==> 2021年01月29日

dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
System.out.println(l.format(dtf));// 2021-01-29  ==> 2021/01/29

六:LocalDate进阶,获取月末、月首、本周一、下周五、每个月的周一

方法说明
LocalDate with(TemporalAdjuster adjuster)使用传递的TemporalAdjuster作为参数来调整此日期时间,并在调整后返回调整后的日期时间的副本
LocalDate with(TemporalField field, long newValue)用于将LocalDate的指定字段设置为新值并返回新的日期时间的副本。此方法可用于更改任何受支持的字段,例如年,月或day-of-month。如果由于不支持该字段或其他原因而无法设置新值,则会引发异常。
LocalDate withMonth(int month)修改LocalDate变量的月份,如LocalDate.parse(“2021-10-30”).withMonth(3)则为2021-03-30
month:从1到12
LocalDate withDayOfMonth(int dayOfMonth)修改LocalDate变量的日,如LocalDate.parse(“2021-10-30”).withDayOfMonth(3)则为2021-10-03 dayOfMonth:从1到28-31
LocalDate withDayOfYear(int dayOfYear)返回当年第几天的日期,如当年第300天是几月几号,dayOfYear从1到365-366
LocalDate withYear(int year)修改LocalDate变量的年份,如LocalDate.parse(“2021-10-30”).withYear(2000)则为2000-10-30 year:从MIN_YEAR到MAX_YEAR

1、LocalDate with(TemporalAdjuster adjuster)

参数:该方法接受调节器作为要使用的调节器的参数。

返回值:该方法将基于此方法返回LocalDate并进行调整。

异常:此方法引发以下异常:

TemporalAdjuster:时间调节器

有的时候,你需要进行一些更加灵活复杂的操作,比如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。

这时,就需要时间调节器 TemporalAdjuster,可以更加灵活地处理日期。

TemporalAdjusters 工具提供了一些通用的功能,并且你还可以新增你自己的功能。

方法说明
static TemporalAdjuster firstDayOfMonth()当前月的第一天
static TemporalAdjuster firstDayOfNextMonth()下一个月的第一天
static TemporalAdjuster firstDayOfNextYear()下一年的第一天
static TemporalAdjuster firstDayOfYear()当年的第一天
static TemporalAdjuster lastDayOfYear()当年的最后一天
static TemporalAdjuster lastDayOfMonth()当月的最后一天
static TemporalAdjuster firstInMonth(DayOfWeek dayOfWeek)某月的第一个星期几
static TemporalAdjuster lastInMonth(DayOfWeek dayOfWeek)某月的最后一个星期几
static TemporalAdjuster dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek)某月的第几个星期几,例如,三月中第二个星期二
static TemporalAdjuster next(DayOfWeek dayOfWeek)(往后不包括当天)下一个星期几是几月几号。若当前为周三,那么next(DayOfWeek.WEDNESDAY)指下一个周三即下周三;next(DayOfWeek.SUNDAY) 指下一个周日即本周日(此时并不是下周日)
static TemporalAdjuster nextOrSame(DayOfWeek dayOfWeek)(往后包括当天)最近星期几的日期。如最近星期五的日期,如果今天是星期五,则返回今天日期,如果今天不是星期五,则返回下周五的日期
static TemporalAdjuster previous(DayOfWeek dayOfWeek)(往前不包括当天)上一个星期几是几月几号。若当前为周三,那么previous(DayOfWeek.WEDNESDAY)指上一个周三即上周三;previous(DayOfWeek.TUESDAY) 指上一个周二即昨天(此时并不是上周二)
static TemporalAdjuster previousOrSame(DayOfWeek dayOfWeek)(往前包括当天)最近星期几的日期。如最近星期五的日期,如果今天是星期五,则返回今天日期,如果今天不是星期五,则返回上周五的日期
LocalDate now = LocalDate.now();
System.out.println("当前时间:"+now); //2021-11-30

//获取当月第一天
System.out.println("当月第一天:"+now.with(TemporalAdjusters.firstDayOfMonth()));// 2021-11-01
//获取本月第2天:
System.out.println("本月第2天:"+now.withDayOfMonth(2)); //2021-11-02
//获取下月第一天
System.out.println("下月第一天:"+now.with(TemporalAdjusters.firstDayOfNextMonth())); //2021-12-01
//获取明年第一天
System.out.println("明年第一天:"+now.with(TemporalAdjusters.firstDayOfNextYear())); //2022-01-01
//获取本年第一天
System.out.println("本年第一天:"+now.with(TemporalAdjusters.firstDayOfYear()));//2021-01-01
//获取当月最后一天,再也不用计算是28,29,30还是31:
System.out.println("当月最后一天:"+now.with(TemporalAdjusters.lastDayOfMonth())); //2021-11-30
//获取本年最后一天
System.out.println("本年最后一天:"+now.with(TemporalAdjusters.lastDayOfYear())); //2021-12-31
//获取当月的第一个星期一
System.out.println("当月的第一个星期一:"+now.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY))); //2021-11-01
//获取当月的最后一个星期一
System.out.println("当月的最后一个星期一:"+now.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY))); //2021-11-29

//获取当月第三周星期五
System.out.println("当月第三周星期五:"+now.with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.FRIDAY))); //2021-11-19
//获取本周一
System.out.println("本周一:"+now.with(DayOfWeek.MONDAY)); //2021-11-29
//获取上周二
System.out.println("上周二:"+now.minusWeeks(1).with(ChronoField.DAY_OF_WEEK, 2)); //2021-11-23
//(往前不包括当天)获取当前日期的上一个周一  如果今天是周一,则返回上周一
System.out.println("上一个周一(不包括当天):"+now.with(TemporalAdjusters.previous(DayOfWeek.MONDAY))); //2021-11-29
//(往前包括当天)最近星期五的日期  如果今天是星期五,则返回今天日期
System.out.println("上一个周一(包括当天):"+now.with(TemporalAdjusters.previousOrSame(DayOfWeek.FRIDAY))); //2021-11-26
//获取下周二
System.out.println("下周二:"+now.plusWeeks(1).with(ChronoField.DAY_OF_WEEK, 2)); //2021-12-07
//(往后不包括当天)获取当前日期的下一个周日 如果今天是周日,则返回下周日的时间  如果今天是星期一,则返回本周日的时间
System.out.println("下一个周日(不包括当天):"+now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY))); //2021-12-05
//(往后包括当天)最近星期五的日期  如果今天是星期五,则返回今天日期
System.out.println("下一个周日(包括当天):"+now.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY))); //2021-12-03

七:LocalDateTime与Date的互转


 public static LocalDateTime dateToLocalDateTime(Date date) {
     Instant instant = date.toInstant();
     ZoneId zoneId = ZoneId.systemDefault();
     return instant.atZone(zoneId).toLocalDateTime();
 }

 
 public static Date localDateTimeToDate(LocalDateTime localDateTime) {
     ZoneId zoneId = ZoneId.systemDefault();
     ZonedDateTime zdt = localDateTime.atZone(zoneId);
     return Date.from(zdt.toInstant());
 }

参考:

LocalDate官方apihttps://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯