文章目录
Java8实战
12.1 LocalDate、LocalTime、Instant、Duration以及Period
12.1.1 使用LocalDate和LocalTime
-
LocalDate
LocalDate date = LocalDate.of(2014,3,18); int year = date.getYear(); Month month = date.getMonth(); int day = date.getDayOfMonth(); DayOfWeek dow = date.getDayOfWeek(); 星期几 int len = date.lengthOfMonth(); 这个月有几天 boolean leap = date.isLeapYear(); LocalDate today = LocalDate.now(); 当前日期 //从系统时钟中获取当前日期 final LocalDate today = LocalDate.now(); //使用Temporal读取LocalDate的值 int year1= date.get(ChronoField.YEAR); int month1= date.get(ChronoField.MONTH_OF_YEAR); int day1= date.get(ChronoField.DAY_OF_MONTH);
运行结果:
2014-03-18 2014 MARCH 18 TUESDAY 31 false 2019-12-23 2020-07-31 2014 3 18
-
LocalTime
LocalTime time = LocalTime.of(13,45,20); int hour = time.getHour(); int minute = time.getMinute(); int second = time.getSecond(); //也可以使用重载方法,自定义如何格式化日期 LocalDate date1 = LocalDate.parse("2014-03-18"); LocalTime time1 = LocalTime.parse("13:45:20");
运行结果:
13:45:20 13 45 20 2014-03-18 13:45:20
12.1.2 合并日期和时间
- LocalDateTime
运行结果LocalDate date = LocalDate.parse("2014-03-18"); LocalTime time = LocalTime.parse("13:45:20"); LocalDateTime dt1 = LocalDateTime.of(2014,Month.MARCH,18,13,45,20); LocalDateTime dt2 = LocalDateTime.of(date,time); //date加一个time转换成LocalDateTime LocalDateTime dt3 = date.atTime(13,15,20); LocalDateTime dt4 = date.atTime(time); //time加一个date转换成LocalDateTime LocalDateTime dt5 = time.atDate(date); LocalDate date1 = dt1.toLocalDate(); LocalTime time1 = dt1.toLocalTime();
2014-03-18T13:45:20 2014-03-18T13:45:20 2014-03-18T13:15:20 2014-03-18T13:45:20 2014-03-18T13:45:20 2014-03-18 13:45:20
12.1.3 机器的日期和时间格式
-
Instant
Instant i1 = Instant.ofEpochSecond(3); -------------------(秒) Instant i2 = Instant.ofEpochSecond(3,0);-----------------(秒,纳秒) Instant i3 = Instant.ofEpochSecond(2,1000000000); Instant i4 = Instant.ofEpochSecond(4,-1000000000);
运行结果:
1970-01-01T00:00:03Z 1970-01-01T00:00:03Z 1970-01-01T00:00:03Z 1970-01-01T00:00:03Z
12.1.4 定义Duration或Period
-
Duration(时间间隔)
-
主要用于以秒和纳秒衡量时间的长短
LocalTime time1 = LocalTime.of(13,45,20); LocalTime finalTime = time1 .plus(Duration.ofSeconds(30)); LocalTime time2 = LocalTime.of(14,48,50); LocalDateTime dateTime1 = LocalDateTime.of(2014,Month.MARCH,18,13,45,20); LocalDateTime dateTime2 = LocalDateTime.of(2016,Month.MARCH,20,15,50,50); Instant instant1 = Instant.ofEpochSecond(4,-1000000000); Instant instant2 = Instant.ofEpochSecond(2,1000000000); Duration d1 = Duration.between(time1,time2); Duration d2 = Duration.between(dateTime1,dateTime2); Duration d3 = Duration.between(instant1,instant2); Period tenDays = Period .between(LocalDate.of(2014,3,8) ,LocalDate.of(2014,3,18)); /**************/ LocalTime time = LocalTime.now(); LocalTime time2 = time.plusMinutes(1).plusSeconds(20); Duration between = Duration.between(time, time2); long distance = Duration.between(time, time2).getSeconds(); long distance2 = ChronoUnit.SECONDS.between(time, time2);
运行结果
PT1H3M30S PT17594H5M30S PT0S P10D /***********/ PT1M20S 80 80
-
Period(日期间隔)
Duration threeMinutes = Duration.ofMinutes(3); Duration threeMinutes2 = Duration.of(3,ChronoUnit.MINUTES); Period tenDays2 = Period.ofDays(10); Period threeWeeks = Period.ofWeeks(3); Period twoYearsSixMonthsOneDay = Period.of(2,6,1); LocalDate date1 = LocalDate.parse("2018-01-01"); LocalDate date2 = LocalDate.parse("2019-02-02"); Period dd = Period.between(date1,date2); int days = Period.between(date1, date2).getDays(); //这块是一个小坑,排除月份的日期相减 long days2 = ChronoUnit.DAYS.between(date1, date2);
运行结果
PT3M PT3M P10D P21D P2Y6M1D date P1Y1M1D days 1 days2 397
12.2 操纵、解析和格式化日期
-
普通操纵日期(以下方法都返回了一个修改了属性的对象,他们不会修改原来的对象)
LocalDate date = LocalDate.of(2014,3,18); //直观方式操纵LocalDate属性 LocalDate date1 = date.withYear(2011); LocalDate date2 = date.withDayOfYear(25); //with----- + -----ChronoField枚举 LocalDate date3 = date.with(ChronoField.MONTH_OF_YEAR,9); //以相对方式修改LocalDate属性 date1 = date.plusWeeks(1); date2 = date.minusYears(3); //with----- + -----ChronoField枚举 date3 = date.plus(6,ChronoUnit.MONTHS);
运行结果:
2014-03-18 2011-03-18 2014-01-25 2014-09-18 2014-03-18 2014-03-25 2011-03-18 2014-09-18
表示时间点的日期-时间类的通用方法
方法 名 | 是否是静态方法 | 描述 |
---|---|---|
from | 是 | 依据传入的Temporal对象创建对象实例 |
now | 是 | 依据系统时钟创建Temporal对象 |
of | 是 | 由Temporal对象的某个部分创建该对象的实例 |
parse | 是 | 由字符串创建Temporal对象的实例 |
atOffset | 否 | 将Temporal对象和某个时区偏移相结合 |
atZone | 否 | 将Temporal对象和某个时区相结合 |
format | 否 | 使用某个指定的格式器将Temporal对象转换为字符串(Instant类不提供该方法) |
get | 否 | 读取Temporal对象的某一部分的值 |
minus | 否 | 创建Temporal对象的一个副本,通过将当前Temporal对象的值减去一定的时长创建该副本 |
plus | 否 | 创建Temporal对象的一个副本,通过将当前Temporal对象的值加上一定的时长创建该副本 |
with | 否 | 以该Temporal对象为模板,对某些状态进行修改创建该对象的副本 |
12.2.1TemporalAdjuster操纵日期
```java
LocalDate date1 = LocalDate.of(2014,3,18);
LocalDate date2 = date1.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
LocalDate date3 = date2.with(TemporalAdjusters.lastDayOfMonth());
```
运行结果
```java
2014-03-18
2014-03-23
2014-03-31
```
方法 | 描述 |
---|---|
dayOfWeekInMonth | 创建一个新的日期,它的值为同一个月中每一周的第几天 |
firstDayOfMonth | 创建一个新的日期,它的值为当月的第一天 |
firstDayOfNextMonth | 创建一个新的日期,它的值为下月的第一天 |
firstDayOfNextYear | 创建一个新的日期,它的值为明年的第一天 |
firstDayOfYear | 创建一个新的日期,它的值为当年的第一天 |
firstInMonth | 创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值 |
lastDayOfMonth | 创建一个新的日期,它的值为当月的最后一天 |
lastDayOfNextMonth | 创建一个新的日期,它的值为下月的最后一天 |
lastDayOfNextYear | 创建一个新的日期,它的值为明年的最后一天 |
lastDayOfYear | 创建一个新的日期,它的值为今年的最后一天 |
lastInMonth | 创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值 |
next / previous | 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期 |
nextOrSame / previousOrSame | 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星期几要求的日期,如果该日期已经符合要求,直接返回该对象 |
12.2.2 打印输出及解析日期-时间对象
- format
运行结果LocalDate date = LocalDate.of(2014,3,18); //使用本来就有的格式转化为字符串 String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); 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"); String formattedDate = date.format(formatter); LocalDate date3 = LocalDate.parse(formattedDate, formatter); DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d.MMMM yyyy", Locale.ITALIAN); formattedDate = date.format((italianFormatter)); date3 = LocalDate.parse(formattedDate,italianFormatter);
2014-03-18 20140318 2014-03-18 2014-03-18 2014-03-18 2014-03-18 Value(DayOfMonth,2)'/'Value(MonthOfYear,2)'/'Value(YearOfEra,4,19,EXCEEDS_PAD) 18/03/2014 2014-03-18 Value(DayOfMonth)'.'Text(MonthOfYear)' 'Value(YearOfEra,4,19,EXCEEDS_PAD) 18.marzo 2014 2014-03-18
12.3 处理不同的时区和历法
- ZoneId
运行结果ZoneId romeZone = ZoneId.of("Europe/Rome"); ZoneId zoneId = TimeZone.getDefault().toZoneId(); //LocalDate ---- ZonedDateTime LocalDate date = LocalDate.of(2014, Month.MARCH, 18); ZonedDateTime zdt1 = date.atStartOfDay(romeZone); //LocalDateTime ---- ZonedDateTime LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13,45); ZonedDateTime zdt2 = dateTime.atZone(romeZone); //Instant ---- ZonedDateTime Instant instant = Instant.now(); ZonedDateTime zdt3 = instant.atZone(romeZone); //LocalDateTime dateTime2 = LocalDateTime.of(2014, Month.MARCH, 18, 13,45); //dateTime2.toInstant(romeZone)-------这里使用错误,不能用ZoneId,而是使用ZoneOffset LocalDateTime dateTime2 = LocalDateTime.ofInstant(instant,romeZone);
Europe/Rome Asia/Shanghai 2014-03-18 2014-03-18T00:00+01:00[Europe/Rome] 2014-03-18T13:45 2014-03-18T13:45+01:00[Europe/Rome] 2020-07-31T08:25:23.478156400Z 2020-07-31T10:25:23.478156400+02:00[Europe/Rome] 2020-07-31T10:25:23.478156400
你应该了解
- 新版的日期和时间API中,日期- 时间对象是不可变的。
- 你可以用绝对或者相对的方式操纵日期和时间,操作的结果总是返回一个新的实例,老的日期时间对象不会发生变化。
简单的使用
- 自制格式器格式化日期
运行结果LocalDateTime dateTime = LocalDateTime.now(ZoneId.of("Asia/Tokyo")); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHhhmmss"); // LocalDateTime--->String String dateTimeStr = formatter.format(dateTime); // String--->LocalDateTime LocalDateTime dateTime2 = LocalDateTime.parse(dateTimeStr, formatter);
2020-07-31T17:43:35.899897400 2020073117054335 2020-07-31T17:43:35