最近撸码中有时间处理的需求,研究了一下java的LocalDate类,记录学习笔记。
需求
获取当前时间,根据当前时间取得下周的周一。
查到的资料
查到的资料,全都是最基础的教你以下知识:
- 获取当前时间
LocalDate localDate = LocalDate.now();
- 获取指定时间
LocalDate localDate = LocalDate.of(2018, 11, 10);
LocalDate localDate = LocalDate.of(2018, Month.NOVEMBER, 10);
- 时间加减
localDate.plusDays(1); // 获取下一天
localDate.plusWeeks(1); // 获取下一周
localDate.plusMonths(1); // 获取下一月
localDate.plusYears(1); // 获取下一年
localDate.minusDays(1); // 获取前一天
localDate.minusWeeks(1); // 获取前一周
localDate.minusMonths(1); //获取前一月
localDate.minusYears(1); //获取前一年
上述方法返回的均是localDate对象的复制,并没有改变localDate的值,此处与Calendar不同。官方文档有说明
4. 快速指定时间(with**方法)
localDate.withDayOfMonth(11); // 设置日期到指定月份
localDate.withDayOfYear(11); // 设定日期到一年中的第几天
localDate.withMonth(11);
localDate.withYear(11);
如何快速指定日期到每周的周几
百度到的博客都没有写明这类需求。
那么如何指定日期到周几?
根据代码提示,可以看到LocalDate有一个with方法public LocalDate with(TemporalField field, long newValue)
那么TemporalField类又是什么?
官方介绍如下
public interface TemporalField
A field of date-time, such as month-of-year or hour-of-minute.
Date and time is expressed using fields which partition the time-line into something meaningful for humans.
Implementations of this interface represent those fields.
The most commonly used units are defined in ChronoField.
Further fields are supplied in IsoFields, WeekFields and JulianFields.
Fields can also be written by application code by implementing this interface.
TemporalField是一个接口,是一个日期时间字段,例如月份或小时,将时间转化为人类可以直观感受到含义的值。最常用的实现类是ChronoField
那么查询一下ChronoField,官方文档
可以发现,ChronoField 提供了各种日期类型的枚举常量,比如
常量 | 含义 |
---|---|
DAY_OF_MONTH | 一个月中的第几天 |
DAY_OF_WEEK | 一周中的第几天 |
DAY_OF_YEAR | 一年中的第几天 |
由此,我们知道public LocalDate with(TemporalField field, long newValue)
方法改如何使用了。代码如下
LocalDate localDate = LocalDate.of(2018, Month.NOVEMBER, 10); // 初始时间设置为2018-11-10, 周六
System.out.println(localDate);
localDate = localDate.plusWeeks(1); // 周数加一, 时间为2018-11-17, 周六
localDate = localDate.with(ChronoField.DAY_OF_WEEK, DayOfWeek.MONDAY.getValue()); // 将时间调整到周一
System.out.println(localDate);
结果为
2018-11-10
2018-11-12
其中,ChronoField.DAY_OF_WEEK
表示要调整时间为一个周内的第几天,DayOfWeek.MONDAY.getValue()
表示周一
with方法可以理解为with(要调整的参数, 值)
上述写法是为了减少代码中的魔法值,避免出现很多没有定义的常量;同时为了适应刚从Calendar类切换过来,符合Calendar类的操作习惯。
还可以用以下方法实现
LocalDate localDate = LocalDate.of(2018, Month.NOVEMBER, 10);
System.out.println(localDate);
localDate = localDate.plusDays(7 - localDate.getDayOfWeek().getValue() + 1); // 当前时间加7天,为2018-11-17,减去当前周几(周六)为2018-11-11,加一天,2018-11-12。代码是给人看的,所以没有把7 + 1合并常数项
System.out.println(localDate);
满足在不知道当前日期或指定日期是周几的时候,获取下一周的周一,不必调用localDate.getDayOfWeek.getValue()
获取日期是周几,然后写if判断该从当前天加几天才能到下周一