记录生活中的点点滴滴

0%

日期和时间API

Java1.0有一个 Date 类,事后证明它过于简单了,当Java1.1引入 Calendar 类之后,Date 类中的大部分方法就被弃用了。但是 Calendar 的API还不够给力,它的实例是易变的。第3次升级很吸引人,那就是Java SE8中引入的 java.time API,它修正了过去的缺陷,并且应该会服役相当长的时间。

时间日期的API

静态方法 now()

这三个日期API里面采用静态方法 now() 获取当前的日期时间

  • 年月日:LocalDate

    1
    2
    3
    4
    5
    6
    //年月日:LocalDate
    @Test
    public void Test1(){
    LocalDate now = LocalDate.now();
    System.out.println(now);//2020-11-11
    }
  • 时分秒:LocalTime

    1
    2
    3
    4
    5
    6
    //时分秒:LocalTime
    @Test
    public void Test2(){
    LocalTime now = LocalTime.now();
    System.out.println(now);//14:29:14.970101600
    }
  • 年月日时分秒:LocalDateTime

    1
    2
    3
    4
    5
    6
    //年月日时分秒:LocalDateTime
    @Test
    public void Test3(){
    LocalDateTime now = LocalDateTime.now();
    System.out.println(now);//2020-11-11T14:29:55.956820300
    }

静态方法 of()

指定年月日,时分秒 使用静态的 of():

1
2
3
4
5
6
7
8
//指定年月日时分秒:指定年月日,时分秒 使用静态的 of():
@Test
public void Test4(){
LocalDateTime time = LocalDateTime.of(2000, 9, 22, 12, 12, 12);
System.out.println(time);//2000-09-22T12:12:12
LocalDate of1 = LocalDate.of(2019, 10, 10);
LocalTime of2 = LocalTime.of(18, 20, 30);
}

获取相关方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void Test1(){
LocalDateTime now = LocalDateTime.now();
//获取年 -- 2020
System.out.println("getYear: "+now.getYear());
//获得月份, 返回一个Month枚举值 -- NOVEMBER
System.out.println("getMonth: " + now.getMonth());
//获得月份(1-12) -- 11
System.out.println("getMonthValue: " + now.getMonthValue());
//获得月份天数(1-31) -- 11
System.out.println("getDayOfMonth: "+now.getDayOfMonth());
//获取小时 -- 16
System.out.println("getHour: "+now.getHour());
//获取分钟 -- 52
System.out.println("getMinute: "+now.getMinute());
//获取秒 -- 53
System.out.println("getSecond: "+now.getSecond());
//获取星期几 -- WEDNESDAY
System.out.println("getDayOfWeek: "+now.getDayOfWeek());
}

格式化方法 format()

1
2
3
4
5
6
7
8
9
10
//格式化日期日期字符串的方法 format()
@Test
public void Test1(){
LocalDateTime now = LocalDateTime.now();
//DateTimeFormatter格式化日期的类
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
//格式化日期的方法
String time = now.format(formatter);
System.out.println(time);//2020年11月11日 16时55分22秒
}

转换相关方法

1
2
3
4
5
6
7
8
9
10
11
//与转换相关的方法
@Test
public void Test5(){
LocalDateTime now = LocalDateTime.now();
//转换成 年月日的这个日期
LocalDate date = now.toLocalDate();
//转换成 时分秒的这个日期
LocalTime time = now.toLocalTime();
System.out.println(date);//2020-11-11
System.out.println(time);//16:56:04.938065900
}

判断相关的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void Test6(){
LocalDate date1 = LocalDate.of(2020, 1, 1);
LocalDate date2 = LocalDate.of(2010, 1, 1);
//isAfter():判断一个日期是否在指定日期之后 -- false
System.out.println("date1是否在date2之前:"+date1.isBefore(date2));
//isBefore():判断一个日期是否在指定日期之前 -- true
System.out.println("date1是否在date2之后:"+date1.isAfter(date2));
//isLeapYear():判断是否是闰年注意是LocalDate类中的方法
//true
System.out.println("date1是否是闰年:"+date1.isLeapYear());
//false
System.out.println("date2是否是闰年:"+date2.isLeapYear());
}

静态方法 parse()

将一个日期字符串解析成日期对象, 注意字符串日期的写法的格式要正确, 否则解析失败

1
2
3
4
5
6
@Test
public void Test1(){
String time = "2000-09-22T12:12:12";
LocalDateTime parse = LocalDateTime.parse(time);
System.out.println(parse);//2000-09-22T12:12:12
}
1
2
3
4
5
6
7
@Test
public void Test2(){
String str = "2000-09-20";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate parse = LocalDate.parse(str, formatter);
System.out.println(parse);//2000-09-20
}
1
2
3
4
5
6
7
@Test
public void Test3(){
String str = "12:30:50";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalTime parse = LocalTime.parse(str, formatter);
System.out.println(parse);//12:30:50
}

添加年月日时分秒的方法

plus 系列的方法:都会返回一个新的 LocalDateTime 的对象

1
2
3
4
5
6
7
8
@Test
public void Test1(){
LocalDate now = LocalDate.now();
LocalDate date = now.plusYears(10);
System.out.println(date);//2030-11-11
LocalDate date1 = date.plusDays(100);
System.out.println(date1);//2031-02-19
}

减去年月日时分秒的方法

minus 系列的方法:注意都会返回一个新的 LocalDateTime 的对象

1
2
3
4
5
6
7
8
@Test
public void Test2(){
LocalDate now = LocalDate.now();
LocalDate date = now.minusYears(10);
System.out.println(date);//2010-11-11
LocalDate date1 = date.minusDays(100);
System.out.println(date1);//2010-08-03
}

指定年月日时分秒的方法

with 系列的方法:注意都会返回一个新的 LocalDateTime 的对象

例如,某个月的下一个星期二可以像下面这样计算:

1
2
LocalDate firstTuesday = LocalDate.of(year,month,1).with(
TemporalAdjusters.nextOrSame(DayOfWeek.TUESDAY));

下面为 TemporalAdjusters 类中的日期调整器:

方法 描述
next(weekday) previous(weekday) 下一个或上一个给定的星期日期
nextOrSame(weekday) previousOrSame(weekday) 从给定日期开始的下一个或上一个给定的星期日期
dayOfWeekInMonth(n, weekday) 月份中的第n个weekday
lastInMonth(weekday) 月份中的最后一个weekday
firstDayofMonth() firstDayofNextMonth()
firstDayofNextYear() lastDayofMonth()
lastDayofYear()
方法名描述的日期
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void Test3(){
LocalDate now = LocalDate.now();//今天2000-11-11,周三
LocalDate date = now.withYear(2000);
System.out.println(date);//2000-11-11

LocalDate date1 = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));//下一个周日
System.out.println(date1);//2020-11-15
LocalDate date2 = now.with(TemporalAdjusters.nextOrSame(DayOfWeek.WEDNESDAY));//从现在开始的下一个周三(包括现在)
System.out.println(date2);//2020-11-11
LocalDate date3 = now.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY));//上一个周日
System.out.println(date3);//2020-11-08

LocalDate date4 = now.with(TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.SUNDAY));//这个月份中第1个周日
System.out.println(date4);//2020-11-01
LocalDate date5 = now.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));//这个月份中最后一个周日
System.out.println(date5);//2020-11-29
}

另外,我们也可以通过实现 TemporalAdjuster 接口来创建自己的调整器,下面是计算下一个工作日的调整器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void Test4(){
LocalDate now = LocalDate.now();//今天11月11号,周三
//定义自己的TemporalAdjuster接口:求下一个工作日(不包括现在)
TemporalAdjuster NEXT_WORKDAY = w->{
LocalDate result = (LocalDate) w;
do {
result = result.plusDays(1);
}while (result.getDayOfWeek().getValue()>=6);
return result;
};
LocalDate date6 = now.with(NEXT_WORKDAY);
System.out.println(date6);//2020-11-12
}

上面lambda表达式的参数w的类型是 Temporal ,它必须被强制转型为 LocalDate

Instant 时间戳类

Instant 时间戳类从1970 -01 - 01 00:00:00 截止到当前时间的毫秒值

静态方法 now 获取对象

1
2
3
4
5
@Test
public void Test1(){
Instant now = Instant.now();
System.out.println(now.toString());//2020-11-11T07:41:46.009176100Z
}

设置偏移量

atOffset() 设置偏移量 返回的是一个偏移后的时间

1
2
3
4
5
6
7
8
9
@Test
public void Test2(){
Instant now = Instant.now();
//默认的是美国时间
System.out.println(now);//2020-11-11T07:39:36.776146700Z
//设置偏移量变为我们中国的时间
OffsetDateTime time = now.atOffset(ZoneOffset.ofHours(8));
System.out.println(time);//2020-11-11T15:39:36.776146700+08:00
}

设置时区

ZoneID 世界时区类

我们可以通过它来设置时区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//ZoneID 世界时区类:
@Test
public void Test1(){
//1.获取世界各个地方的时区的集合 的方法getAvailableZoneIds()
//使用ZoneID中的静态方法getAvailableZoneIds();来获取
Set<String> Ids = ZoneId.getAvailableZoneIds();
Ids.forEach(s-> System.out.println(s));

//2.获取系统默认时区的ID
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);//Asia/Shanghai

//3.获取带有时区的日期时间对象
ZoneId newYork_id = ZoneId.of("America/New_York");
LocalDateTime time1 = LocalDateTime.now(newYork_id);
System.out.println(time1);//2020-11-11T03:08:57.678275800
}

get系列的方法:

  • getEpochSecond():获取从1970-01-01 00:00:00到当前时间的秒值
  • toEpochMilli() :是把获取到的当前时间的秒数 换算成毫秒
  • getNano():是把获取到的当前时间的秒数 换算成纳秒
1
2
3
4
5
6
7
8
9
10
11
12
//getEpochSecond():
//获取从1970-01-01 00:00:00到当前时间的秒值
@Test
public void Test3(){
Instant now = Instant.now();
//获取当前的毫秒值
long l = now.toEpochMilli();
//获取当前的秒值
long epochSecond = now.getEpochSecond();
System.out.println("毫秒值:\t"+l);//1605080750971
System.out.println("秒值: \t"+epochSecond);//1605080750
}
1
2
3
4
5
6
7
8
9
10
@Test
public void Test1(){
Instant now = Instant.now();
System.out.println(now.toString());//2020-11-11T07:41:46.009176100Z
//获取当前时间的毫秒
long l1 = now.toEpochMilli();
long l2 = System.currentTimeMillis();
System.out.println(l1);//1605080506009
System.out.println(l2);//1605080506018
}

Duration与Period

Duration:用于计算两个“时间”间隔的类

1
2
3
4
5
6
7
8
9
10
11
12
//Duration:
//用于计算两个“时间”间隔的类
@Test
public void Test1(){
Instant start = Instant.now();
for (long i = 0; i < 1000000; i++) {
System.out.println("hello");
}
Instant end = Instant.now();
Duration between = Duration.between(start, end);
System.out.println(between.getSeconds());//7
}

Period:用于计算两个“日期”间隔的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Period:
//用于计算两个“日期”间隔的类
@Test
public void Test1(){
LocalDate start = LocalDate.of(2000, 9, 22);
LocalDate end = LocalDate.of(2020, 11, 11);
Period between = Period.between(start, end);
int years = between.getYears();
int months = between.getMonths();
int days = between.getDays();
System.out.println(years);//20
System.out.println(months);//1
System.out.println(days);//20
}

DateTimeFormatter类

解析和格式化日期或时间的类

通过静态方法 ofPattern(“yyyy-MM-dd”) 来获取对象;

1
2
3
4
5
6
7
8
9
10
//格式化日期日期字符串的方法 format()
@Test
public void Test1(){
LocalDateTime now = LocalDateTime.now();
//DateTimeFormatter格式化日期的类
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
//格式化日期的方法
String time = now.format(formatter);
System.out.println(time);//2020年11月11日 16时55分22秒
}