摘要:这个月的天数是否事闰年似地,一天中的时间,比如,可以使用类表示。使用静态方法,你可以实现这一目的合并日期和时间这个复合类名叫,是和的合体。对于最常见的用例,日期和时间已经提供了大量预定义的。
Java的API提供了很多有用的组件,能帮助你构建复杂的应用。不过,Java API也不总是完美的。我们相信大多数有经验的程序员都会赞同Java 8之前的库对日期和时间的支持就非常不理想。然而,你也不用太担心:Java 8中引入全新的日期和时间API就是要解决这一问题。
1 LocalDate 、 LocalTime 、 Instant 、 Duration 以及 Period让我们从探索如何创建简单的日期和时间间隔入手。 java.time 包中提供了很多新的类可以帮你解决问题,它们是 LocalDate 、 LocalTime 、 Instant 、 Duration 和 Period 。
LocalDate 类,该类的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关的信息。
你可以通过静态工厂方法 of 创建一个 LocalDate 实例。 LocalDate 实例提供了多种方法来读取常用的值,比如年份、月份、星期几等。
public static void main(String[] args) {
//2014-3-18
LocalDate date = LocalDate.of(2014, 3, 18);
//2014
int year = date.getYear();
//march
Month month = date.getMonth();
//18
int day = date.getDayOfMonth();
DayOfWeek dow = date.getDayOfWeek();
//这个月的天数
int len = date.lengthOfMonth();
//是否事闰年
boolean leap = date.isLeapYear();
System.out.println("year : " + year + " month : " + month + " day : " + day +
" dow : " + dow + " len : " + len + " leap : " + leap);
}
似地,一天中的时间,比如13:45:20,可以使用 LocalTime 类表示。你可以使用 of 重载的两个工厂方法创建 LocalTime 的实例。第一个重载函数接收小时和分钟,第二个重载函数同时还接收秒。同 LocalDate 一样, LocalTime 类也提供了一些 getter 方法访问这些变量的值。
LocalTime time = LocalTime.of(13, 45, 20); int hour = time.getHour(); int minute = time.getMinute(); int second = time.getSecond();
LocalDate 和 LocalTime 都可以通过解析代表它们的字符串创建。使用静态方法 parse ,你可以实现这一目的:
LocalDate date = LocalDate.parse("2014-03-18");
LocalTime time = LocalTime.parse("13:45:20");
这个复合类名叫 LocalDateTime ,是 LocalDate 和 LocalTime 的合体。它同时表示了日期和时间,但不带有时区信息,你可以直接创建,也可以通过合并日期和时间对象构造。
// 2014-03-18T13:45:20 LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20); LocalDateTime dt2 = LocalDateTime.of(date, time); LocalDateTime dt3 = date.atTime(13, 45, 20); LocalDateTime dt4 = date.atTime(time); LocalDateTime dt5 = time.atDate(date);
通过它们各自的 atTime 或者 atDate 方法,向 LocalDate 传递一个时间对象,或者向LocalTime 传递一个日期对象的方式,你可以创建一个 LocalDateTime 对象。你也可以使用toLocalDate 或者 toLocalTime 方法,从 LocalDateTime 中提取 LocalDate 或者 LocalTime组件:
LocalDate date1 = dt1.toLocalDate(); LocalTime time1 = dt1.toLocalTime();
Duration 类的静态工厂方法 between 就是为比较两个时间而设计的。你可以创建两个 LocalTimes 对象、两个 LocalDateTimes对象,或者两个 Instant 对象之间的 duration:
Duration d1 = Duration.between(time1, time2); Duration d1 = Duration.between(dateTime1, dateTime2);
如果你需要以年、月或者日的方式对多个时间单位建模,可以使用 Period 类。使用该类的工厂方法 between ,你可以使用得到两个 LocalDate 之间的时长:
Period tenDays = Period.between(LocalDate.of(2014, 3, 8), LocalDate.of(2014, 3, 18));
最后, Duration 和 Period 类都提供了很多非常方便的工厂类,直接创建对应的实例;换句话说,就像下面这段代码那样,不再是只能以两个temporal对象的差值的方式来定义它们的对象。
Duration threeMinutes = Duration.ofMinutes(3); Duration threeMinutes = Duration.of(3, ChronoUnit.MINUTES); Period tenDays = Period.ofDays(10); Period threeWeeks = Period.ofWeeks(3); Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1);
Duration 类和 Period 类共享方法
2 操纵、解析和格式化日期
//2019-3-20
LocalDate of = LocalDate.of(2019, 3, 20);
//2018-3-20
LocalDate localDate = of.withYear(2018);
//2018-4-20
LocalDate localDate1 = localDate.withMonth(4);
//2018-9-20
LocalDate with = localDate1.with(ChronoField.MONTH_OF_YEAR, 9);
最后这一行中使用的 with 方法和get方法有些类似,它们都声明于 Temporal 接口,所有的日期和时间API类都实现这两个方法,它们定义了单点的时间,比如 LocalDate 、 LocalTime 、 LocalDateTime 以及 Instant 。更确切 地说,使用 get 和 with 方法,我们可以将 Temporal 对象值的读取和修改区分开。
//2014-3-18 LocalDate date1 = LocalDate.of(2014, 3, 18); //2014-3-25 LocalDate date2 = date1.plusWeeks(1); LocalDate date3 = date2.minusYears(3); LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);
最后一行使用的 plus 方法也是通用方法,它和 minus 方法都声明于 Temporal 接口中。通过这些方法,对 TemporalUnit 对象加上或者减去一个数字,我们能非常方便地将 Temporal 对象前溯或者回滚至某个时间段,通过ChronoUnit 枚举我们可以非常方便地实现 TemporalUnit 接口。
有的时候,你需要进行一些更加复杂的操作,比如,将日期调整到下个周日、下个工作日,或者是本月的最后一天。这时,你可以使用重载版本的 with 方法,向其传递一个提供了更多定制化选择的 TemporalAdjuster 对象,更加灵活地处理日期。对于最常见的用例,日期和时间API已经提供了大量预定义的TemporalAdjuster 。你可以通过 TemporalAdjuster 类的静态工厂方法访问它们。
//2014-03-18 LocalDate date1 = LocalDate.of(2014, 3, 18); //2014-03-23 LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY)); //2014-03-31 LocalDate date3 = date2.with(lastDayOfMonth());
正如我们看到的,使用 TemporalAdjuster 我们可以进行更加复杂的日期操作,而且这些方 法的名称也非常直观,方法名基本就是问题陈述。此外,即使你没有找到符合你要求的预定义的 TemporalAdjuster ,创建你自己的 TemporalAdjuster 也并非难事。实际上, Temporal- Adjuster 接口只声明了单一的一个方法(这使得它成为了一个函数式接口)。
@FunctionalInterface public interface TemporalAdjuster { Temporal adjustInto(Temporal temporal); }
这意味着 TemporalAdjuster 接口的实现需要定义如何将一个 Temporal 对象转换为另一个 Temporal 对象。你可以把它看成一个 UnaryOperator
设计一个 NextWorkingDay 类,该类实现了 TemporalAdjuster 接口,能够计算明天的日期,同时过滤掉周六和周日这些节假日。格式如下所示:
public class MyTemporalAdjuster {
public static void main(String[] args) {
LocalDate of = LocalDate.of(2019, 3, 20);
LocalDate with = of.with(new NewTemporalAdjuster());
System.out.println("with = " + with);
}
}
//如果当天的星期介于周一至周五之间,日期向后移动一天;如果当天是周六或者周日,则返回下一个周一
class NewTemporalAdjuster implements TemporalAdjuster {
@Override
public Temporal adjustInto(Temporal temporal) {
DayOfWeek of = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
int dayToAdd = 1;
if (of == DayOfWeek.FRIDAY){
dayToAdd = 3;
}else if (of == DayOfWeek.SATURDAY){
dayToAdd = 2;
}
return temporal.plus(dayToAdd, ChronoUnit.DAYS);
}
}
处理日期和时间对象时,格式化以及解析日期时间对象是另一个非常重要的功能。新的java.time.format 包就是特别为这个目的而设计的。这个包中,最重要的类是 DateTimeFormatter 。创建格式器最简单的方法是通过它的静态工厂方法以及常量。像 BASIC_ISO_DATE和 ISO_LOCAL_DATE 这 样 的 常 量 是 DateTimeFormatter 类 的 预 定 义 实 例 。 所 有 的DateTimeFormatter 实例都能用于以一定的格式创建代表特定日期或时间的字符串。
LocalDate date = LocalDate.of(2014, 3, 18); //20140318 String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); //2014-03-18 String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
你也可以通过解析代表日期或时间的字符串重新创建该日期对象。所有的日期和时间API都提供了表示时间点或者时间段的工厂方法,你可以使用工厂方法 parse 达到重创该日期对象的目的:
LocalDate date1 = LocalDate.parse("20140318",DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2014-03-18",DateTimeFormatter.ISO_LOCAL_DATE);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date1 = LocalDate.of(2014, 3, 18);
String formattedDate = date1.format(formatter);
LocalDate date2 = LocalDate.parse(formattedDate, formatter);
LocalDate 的 formate 方法使用指定的模式生成了一个代表该日期的字符串。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/7115.html
摘要:这个月的天数是否事闰年似地,一天中的时间,比如,可以使用类表示。使用静态方法,你可以实现这一目的合并日期和时间这个复合类名叫,是和的合体。对于最常见的用例,日期和时间已经提供了大量预定义的。Java的API提供了很多有用的组件,能帮助你构建复杂的应用。不过,Java API也不总是完美的。我们相信大多数有经验的程序员都会赞同Java 8之前的库对日期和时间的支持就非常不理想。然而,你也不用太...
摘要:这个月的天数是否事闰年似地,一天中的时间,比如,可以使用类表示。使用静态方法,你可以实现这一目的合并日期和时间这个复合类名叫,是和的合体。对于最常见的用例,日期和时间已经提供了大量预定义的。Java的API提供了很多有用的组件,能帮助你构建复杂的应用。不过,Java API也不总是完美的。我们相信大多数有经验的程序员都会赞同Java 8之前的库对日期和时间的支持就非常不理想。然而,你也不用太...
摘要:线程挂起,线程继续走,还会被继续使用方法,而这时用的是线程设置的值了,而这就是引发问题的根源,出现时间不对,线程挂死等等。建议为每个线程创建单独的格式实例。其中工作队列使用的是,源码头部的注释中有说明截取的部分。 阅读本文大概需要 3.2 分钟。 前言 日常开发中,我们经常需要使用时间相关类,想必大家对SimpleDateFormat并不陌生。主要是用它进行时间的格式化输出和解析,...
摘要:所以说我们的线程最好是交由线程池来管理,这样可以减少对线程生命周期的管理,一定程度上提高性能。线程池不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。当所有的任务已终止,记录的任务数量为,线程池会变为状态。线程池彻底终止的状态。 前言 只有光头才能变强 回顾前面: ThreadLocal就是这么简单 多线程三分钟就可以入个门了! 多线程基础必要知识点!看了学习多线程事半功倍...
摘要:时间年月日星期四说明本文部分内容均来自慕课网。那么里面的数据就可以分为各种各样的索引,比如汽车索引图书索引家具索引等等。图书索引又可以细分为各种类型,比如科普类小说类技术类等等。具体到每一本书籍,就是文档,就是整个图书里面最小的存储单位。 时间:2017年09月14日星期四说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学源码:无学习源码:https...
阅读 682·2023-04-25 19:43
阅读 3855·2021-11-30 14:52
阅读 3729·2021-11-30 14:52
阅读 3795·2021-11-29 11:00
阅读 3745·2021-11-29 11:00
阅读 3812·2021-11-29 11:00
阅读 3528·2021-11-29 11:00
阅读 6009·2021-11-29 11:00