java日期和时间api

概述

java8之后推出了新的time api.

java.time包下有5个包组成(大部分人用到基础包和format包就足够了)

  • java.time – 包含值对象的基础包
  • java.time.chrono – 提供对不同的日历系统的访问
  • java.time.format – 格式化和解析时间和日期
  • java.time.temporal – 包括底层框架和扩展特性
  • java.time.zone – 包含时区支持的类

注意:java.time包下所有类都是不可变的、线程安全的

规范

java的DateTime API规范要求Java使用的时间尺度为:

  • 每天86400
  • 每天正午与官方时间精准匹配
  • 在时间点上,以精确的方式与官方时间接近匹配

Instant

java中,Instant表示时间线上的某一点。、该时间线的原点为:穿过伦敦格林威治皇家天文台的本初子午线所处时区 的1970年1月1日的午夜`

Instant的常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Instant now() //获取当前时间

long getEpochSecond()
long toEpochMilli()
int getNano()

Instant plusMillis(long millisToAdd)//返回当前时间增加指定毫秒数后的时间
Instant plusNanos(long millisToAdd)//返回当前时间增加指定纳秒数后的时间
Instant plusSeconds(long millisToAdd)//返回当前时间增加指定秒数后的时间

boolean isAfter(Instant otherInstant);
boolean instant.isBefore(Instant otherInstant);

MIN //最小值,代表原点前的十亿年
MAX //最大值,代表公元 1000 000 000年的12月31日

实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 public static void main(String[] args) throws Exception {
Instant instant = Instant.now();
System.out.println(instant.toString());
System.out.println(instant.getEpochSecond());//返回从原点到现在的秒数
System.out.println(instant.getNano());//当前一秒内的第几纳秒
System.out.println(instant.toEpochMilli());//返回从原点到现在的毫秒数
System.out.println(instant.plusMillis(10000));
System.out.println(instant.plusNanos(1000));;
System.out.println(instant.plusSeconds(1000));;
}

结果:

2019-04-11T01:38:22.067Z
1554946702
67000000
1554946702067
2019-04-11T01:38:32.067Z
2019-04-11T01:38:22.067001Z
2019-04-11T01:55:02.067Z

Duration

Duration是两个时刻之间的时间量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Instant start = Instant.now();
run();//延时方法
Instant end = Instant.now();
Duration t = Duration.between(start,end);
System.out.println(t.toDays());//获取时间经过的天数
System.out.println(t.toHours());//获取时间经过的小时数
System.out.println(t.toMinutes());//获取时间经过的分钟数
System.out.println(t.getSeconds());//获取时间经过的秒数
System.out.println(t.toMillis());//获取时间经过的毫秒数
System.out.println(t.toNanos());//获取时间经过的纳秒数
System.out.println(t.toString());
System.out.println(t.getNano());//和Instant.getNano()方法相同

Duration plus = t.plusDays(1);//在当前Duration加上指定天数的时间,其他plusXXX()不再介绍
Duration min = t.minusDays(1);//在当前Duration减去指定天数的时间,其他minusXXX()不再介绍

本地时间

转载java 8的java.time包(非常值得推荐)

  • LocalDateTime:存储了日期和时间
  • LocalDate:只存储了日期
  • LocalTime:只存储了时间,如:14:02:43.455。(后面的.455表示毫秒值的最后三位,使用.withNano(0)可把毫秒值设为0)

java.time.LocalDateTime

此类显示的是年月日时分秒(默认的格式为:2017-01-01T01:01:01.555)

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
LocalDateTime now = LocalDateTime.now();
System.out.println(now.toString());
System.out.println(now.getYear());
System.out.println(now.getMonthValue());
System.out.println(now.getDayOfMonth());
System.out.println(now.getHour()); //24小时制
System.out.println(now.getMinute());
System.out.println(now.getSecond());
System.out.println(now.getNano()); //毫秒值的后三位作为前三位后面补6个零

打印的结果为:
2017-03-21T20:26:18.317
2017
3
21
20
26
18
317000000

//能够自定义时间
LocalDateTime time = LocalDateTime.of(2017, 1, 1, 1, 1,1);
System.out.println(time); //2017-01-01T01:01:01

//使用plus方法增加年份
LocalDateTime time = LocalDateTime.of(2017, 1, 1, 1, 1,1);

//改变时间后会返回一个新的实例nextYearTime
LocalDateTime nextYearTime = time.plusYears(1);

System.out.println(nextYearTime); //2018-01-01T01:01:01

//使用minus方法减年份
LocalDateTime time = LocalDateTime.of(2017, 1, 1, 1, 1,1);
LocalDateTime lastYearTime = time.minusYears(1);
System.out.println(lastYearTime); //2016-01-01T01:01:01

//使用with方法设置月份
LocalDateTime time = LocalDateTime.of(2017, 1, 1, 1, 1,1);
LocalDateTime changeTime = time.withMonth(12);
System.out.println(changeTime); //2017-12-01T01:01:01

//判断当前年份是否闰年
System.out.println("isLeapYear :" + time.isLeapYear());

//判断当前日期属于星期几
LocalDateTime time = LocalDateTime.now();
DayOfWeek dayOfWeek = time.getDayOfWeek();
System.out.println(dayOfWeek); //WEDNESDAY

LocalDate

此类显示的是年月日(默认的格式为:2017-01-01)
用法与LocalDateTime类大致一样

LocalTime

此类显示的是时分秒和毫秒值的后三位(21:26:35.693)
用法与LocalDateTime类大致一样

TemporalAdjusters

TemporalAdjusters是调节器,通过with方法来调节时间

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
public static TemporalAdjuster ofDateAdjuster(UnaryOperator<LocalDate> dateBasedAdjuster);

public static TemporalAdjuster firstDayOfMonth();

public static TemporalAdjuster lastDayOfMonth()

public static TemporalAdjuster firstDayOfNextMonth();

public static TemporalAdjuster firstDayOfYear();

public static TemporalAdjuster lastDayOfYear();

public static TemporalAdjuster firstDayOfNextYear()

public static TemporalAdjuster firstInMonth(DayOfWeek dayOfWeek);

public static TemporalAdjuster lastInMonth(DayOfWeek dayOfWeek);

public static TemporalAdjuster dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek);

public static TemporalAdjuster next(DayOfWeek dayOfWeek);

public static TemporalAdjuster nextOrSame(DayOfWeek dayOfWeek);

public static TemporalAdjuster previous(DayOfWeek dayOfWeek);

public static TemporalAdjuster previousOrSame(DayOfWeek dayOfWeek);
1
2
LocalDate now = LocalDate.now();
System.out.println(now.with(TemporalAdjusters.firstDayOfMonth()));

DateTimeFormatter

转载java 8的java.time包(非常值得推荐)

此类的功能与SimpleDateFormat类的功能类似,此类也是线程安全的,在写成时间处理工具类时,可作为静态成员变量,而不用每次都new一个SimpleDateFormat实例,此类是用来创建日期显示的模板,然后对于日期的格式化和解析还是使用LocalDateTime等类的parse静态方法和format方法,其模板属性格式是和SimpleDateFormat一样的,请看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
G 年代标志符
y 年
M 月
d 日
h 时 (12小时制)
H 时 (24小时制)
m 分
s 秒
S 毫秒
E 星期几
D 一年中的第几天
F 一月中第几个星期(以每个月1号为第一周,8号为第二周为标准计算)
w 一年中第几个星期
W 一月中第几个星期(不同于F的计算标准,是以星期为标准计算星期数,例如1号是星期三,是当月的第一周,那么5号为星期日就已经是当月的第二周了)
a 上午 / 下午 标记符
k 时 (24小时制,其值与H的不同点在于,当数值小于10时,前面不会有0)
K 时 (12小时值,其值与h的不同点在于,当数值小于10时,前面不会有0)
z 时区

对于此类使用先来个简单的新旧api对比演示:

Date转String

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  //使用Date和SimpleDateFormat
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("G yyyy年MM月dd号 E a hh时mm分ss秒");

String format = simpleDateFormat.format(new Date());

System.out.println(format);
//打印: 公元 2017年03月21号 星期二 下午 06时38分20秒


//使用jdk1.8 LocalDateTime和DateTimeFormatter
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter pattern =
DateTimeFormatter.ofPattern("G yyyy年MM月dd号 E a hh时mm分ss秒");
String format = now.format(pattern);
System.out.println(format);
//打印: 公元 2017年03月21号 星期二 下午 06时38分20秒

String转Date

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 //使用Date和SimpleDateFormat
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

Date date = simpleDateFormat.parse("2017-12-03 10:15:30");

System.out.println(simpleDateFormat.format(date));
//打印 2017-12-03 10:15:30

//使用jdk1.8 LocalDateTime和DateTimeFormatter
DateTimeFormatter pattern =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

//严格按照ISO yyyy-MM-dd验证,03写成3都不行
LocalDateTime dt = LocalDateTime.parse("2017-12-03 10:15:30",pattern);

System.out.println(dt.format(pattern));