日期处理

-


LocalDate & LocalTime & LocalDateTime

创建实例

  • of
  • from
  • now
  • parse

实例都是不可变对象。

读取值

  • getXXX
  • get(TemporalField)

合并日期和时间

  • LocalDateTime.of
  • date.atTime
  • time.atDate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args){
LocalDate ld = LocalDate.of(2020, 1, 2);
LocalDate ldNow = LocalDate.now();
LocalDate ld2 = LocalDate.from(ld);
LocalTime lt = LocalTime.parse("12:20:30");

System.out.println(ld);
System.out.println(ldNow);

int year = ldNow.getYear();
int month = ldNow.get(ChronoField.MONTH_OF_YEAR);
int day = ldNow.get(ChronoField.DAY_OF_MONTH);
int hour = lt.getHour();
int minute = lt.get(ChronoField.MINUTE_OF_HOUR);

System.out.println(year + "-" + month + "-" + day + " " + hour + ":" + minute);

// 2020-01-02
// 2020-01-03
// 2020:1:3
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static void main(String[] args) {

LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();

LocalDateTime ldt = LocalDateTime.of(2020, 1, 3, 11, 54, 20);
LocalDateTime ldt2 = LocalDateTime.of(date, time);
LocalDateTime ldt3 = date.atTime(time);
LocalDateTime ldt4 = time.atDate(date);

LocalDate date2 = ldt.toLocalDate();
LocalTime time2 = ldt.toLocalTime();


System.out.println(ldt);
System.out.println(ldt2);
System.out.println(ldt3);
System.out.println(ldt4);

System.out.println(date2);
System.out.println(time2);

// 2020-01-03T11:54:20
// 2020-01-03T11:58:00.987
// 2020-01-03T11:58:00.987
// 2020-01-03T11:58:00.987
// 2020-01-03
// 11:54:20
}

Instant

以 Unix 元年时间(UTC 时区 1970 年 1 月 1 日午夜时分)到现在的秒数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Instant instant = Instant.now();
long timeInSeconds = instant.getEpochSecond();
Instant instant2 = Instant.ofEpochSecond(timeInSeconds);
Instant instant3 = instant2.plus(10, ChronoUnit.SECONDS);

System.out.println(instant);
System.out.println(timeInSeconds);
System.out.println(instant2);
System.out.println(instant3);

// 2020-01-03T06:45:00.782Z
// 1578033900
// 2020-01-03T06:45:00Z
// 2020-01-03T06:45:10Z

Duration & Period

以上所有的类都实现了Temporal接口,Temporal 接口定义了如何读取和操纵为时间建模的对象的值。Duration、Period 描述了两个 Temporal 对象之间的时间间隔。Duraion 主要用于以秒和纳秒衡量时间的长短。需要以年、月或者日的方式对时间单位建模则可使用 Period。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
LocalDate ld1 = LocalDate.of(2020, 1, 3);
LocalDate ld2 = LocalDate.of(2020, 5, 4);

Period period = Period.between(ld1, ld2);
int days = period.getDays();

System.out.println(ld1);
System.out.println(ld2);
System.out.println(period);
System.out.println(days);

period = period.plusDays(10);

LocalDate ld3 = ld2.plus(period);
System.out.println(ld3);

// 2020-01-03
// 2020-05-04
// P4M1D
// 1
// 2020-09-15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
LocalDateTime ldt1 = LocalDateTime.now();
LocalDateTime ldt2 = ldt1.plusHours(1);

Duration duration = Duration.between(ldt1, ldt2);
duration = duration.plusHours(1);

System.out.println(ldt1);
System.out.println(ldt2);
LocalDateTime ldt3 = ldt2.plus(duration);

System.out.println(duration);
System.out.println(ldt3);

Instant instant1 = Instant.now();
Instant instant2 = instant1.plusSeconds(10);

Duration duration2 = Duration.between(instant1, instant2);

System.out.println(duration2);

// 2020-01-03T15:24:39.551
// 2020-01-03T16:24:39.551
// PT2H
// 2020-01-03T18:24:39.551
// PT10S

修改日期

withAttribute

withAttribute 会创建对象的一个副本。

1
2
3
4
5
6
7
8
9
10
11
12
LocalDate ld = LocalDate.now();
System.out.println(ld);

LocalDate ld2 = ld.withYear(2021);
LocalDate ld3 = ld.with(ChronoField.MONTH_OF_YEAR, 6);

System.out.println(ld2);
System.out.println(ld3);

// 2020-01-03
// 2021-01-03
// 2020-06-03

plus minus

1
2
3
4
5
6
7
LocalDate ld1 = LocalDate.now();
Period period = Period.ofDays(10);
LocalDate ld2 = ld1.plus(period);

System.out.println(ld1);
System.out.println(period);
System.out.println(ld2);

TemporalAdjuster

上面两种对日期的操作是比较直接的方式。如需要复杂操作,比如将日期调整到下个周日、或者本月最后一天,建议使用TemporalAdjusters,已经提供了许多常用的预定义的 TemporalAdjuster。当然,可以实现 TemporanAdjuster 接口自定义日期操作。

1
2
3
4
5
6
7
LocalDate ld1 = LocalDate.now();

System.out.println(ld1.with(TemporalAdjusters.firstDayOfMonth()));
// 这个日期的当前月的第二个星期一的日期
System.out.println(ld1.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY)));
System.out.println(ld1.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)));
System.out.println(ld1.with(TemporalAdjusters.nextOrSame(DayOfWeek.FRIDAY)));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.temporal.TemporalUnit;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;

class NextWorkingDay implements TemporalAdjuster {

@Override
public Temporal adjustInto(Temporal temporal) {
DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));

int dayToAdd = 1;
if (dow == DayOfWeek.FRIDAY) {
dayToAdd = 3;
} else if (dow == DayOfWeek.SATURDAY) {
dayToAdd = 2;
}

return temporal.plus(dayToAdd, ChronoUnit.DAYS);
}

}

public class Test {

public static void main(String[] args) {

LocalDate ld1 = LocalDate.now();

System.out.println(ld1.with(new NextWorkingDay()));

// 也可以使用lambda
LocalDate ld2 = ld1.with(temporal -> {
DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));

int dayToAdd = 1;
if (dow == DayOfWeek.FRIDAY) {
dayToAdd = 3;
} else if (dow == DayOfWeek.SATURDAY) {
dayToAdd = 2;
}

return temporal.plus(dayToAdd, ChronoUnit.DAYS);
});

System.out.println(ld2);

}
}

打印解析日期

  • DateTimeFormatter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LocalDate ld = LocalDate.now();
String s1 = ld.format(ISO_DATE);
String s2 = ld.format(BASIC_ISO_DATE);

System.out.println(ld);
System.out.println(s1);
System.out.println(s2);

LocalDate date1 = LocalDate.parse("20191221", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2020-12-21", DateTimeFormatter.ISO_DATE);

System.out.println(date1);
System.out.println(date2);

// 自定义格式器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String s3 = ld.format(formatter);

System.out.println(s3);

时区 ZoneId

时区是按照一定的规则将区域划分成标准时间相同的区间。
表达时区两种方法。

  • ZoneId.of("Asia/Shanghai")
  • 利用当前时区和 UTC/格林尼治的固定偏差ZoneOffset.of("-05:00")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
LocalDate ld = LocalDate.now();
ZoneId shanghaiZone = ZoneId.of("Asia/Shanghai");
ZonedDateTime zdt = ld.atStartOfDay(shanghaiZone);

System.out.println(ld);
System.out.println(shanghaiZone);
System.out.println(zdt);

LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt1 = ldt.atZone(shanghaiZone);

System.out.println(ldt);
System.out.println(zdt1);

Instant instant = Instant.now();
ZonedDateTime zdt2 = instant.atZone(shanghaiZone);
System.out.println(zdt2);

ZoneId zoneId = ZoneOffset.of("+08:00");
ZonedDateTime zdt3 = instant.atZone(zoneId);
System.out.println(zdt3);


  datejava
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×