Java8 中的时间和日期 API

时间:2022-06-05 22:06:41

1. 日期和时间概述

  1. LocalDate,LocalTime,LocalDateTime类的实例是不可变的对象,分别表示使用 ISO-8601 日历系统
    的日期,时间,日期和时间;它们提供了简单的日期和时间,并不包含当前的时间信息;也不包含与时区相关的信息;
  2. Instant: 时间戳(指定时间与 1970年1月1日 00:00:00 之间的毫秒值);
  3. Duration: 计算两个"时间"之间的间隔;
  4. Period: 计算两个"日期"之间的间隔;
// 测试类
public class TestLocalDateTime{

// 1. LocalDate, LocalTime, LocalDateTime
@Test
public void test(){
// 获取当前时间
LocalDateTime ldt = LocalDateTime.now();

System.out.println(ldt);

// 将当前时间中的日变成 10 日
LocalDateTime ldt5 = ldt.withDayOfMonth(10);
System.out.println(ldt5);

// 获取指定时间, 例如,指定 2017年10月2日,12时13分24秒
LocalDateTime ldt2 = LocalDateTime.of(2017,10,2,12,13,24);
System.out.println(ldt2);

// 时间的加减,都会产生一个新的实例
// 在当前时间的基础上,加两年
LocalDateTime ldt3 = ldt.plusYears(2); // 加两年
System.out.println(ldt3);

LocalDateTime ldt4 = ldt.minusMonths(2);
System.out.println(ldt4);

// 获取年(或月)
System.out.println(ldt.getYear());
System.out.println(ldt.getMonth()); // 返回 Month 对象
System.out.println(ldt.getMonthValue()); // 返回 int 类型

}

// 2. Instant
@Test
public void test2(){
Instant ins = Instant.now(); // 默认获取 UTC 时区
System.out.println(ins);

// 转换为中国时区,即带偏移量运算
OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
System.out.println(odt);

// 将ins转换成毫秒
System.out.println(ins.toEpochMilli());

// 将指定的毫秒转换为时间
Instant ins2 = Instant.ofEpochSecond(60);
System.out.println(ins2);
}

// 3. Duration / Period
@Test
public void test3(){
// 计算两个时间的间隔 Duration
Instant ins = Instant.now();

try{
Thread.sleep(1000);
}catch(InterruptedException e){

}

Instant ins2 = Instant.now();

Duration duration = Duration.between(ins,ins2);
System.out.println(duration.toMillis()); // 获取毫秒值
System.out.println(duration.getSeconds()); // 获取秒


// 计算两个日期的间隔 Period
LocalDate ld = LocalDate.of(2017,10,1);
LocalDate ld2 = LocalDate.now();

Period period = Period.between(ld, ld2);
System.out.println(period);
System.out.println(period.getYears());
}
}

2. 日期的操纵

  • TemporalAdjuster 接口: 时间校正器;例如,将日期调整到"下个周日"的操作;
  • TemporalAdjusters: 该类通过静态方法,提供了大量的常用TemporalAdjuster的实现;
// 测试类
public class TestDate{

// TemporalAdjuster
@Test
public void test(){
LocalDate ldt = LocalDate.now();

// 获取下个周日
LocalDate nextSunday = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
}
}

3. 日期格式化

// 测试类
public class TestDate{

// DateTimeFormatter: 格式化时间或日期
@Test
public void test(){
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE;
LocalDateTime ldt = LocalDateTime.now();

String str = ldt.format(dtf);
System.out.println(str);

// 自定义格式
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
String str2 = dtf2.format(ldt);
System.out.println(str2);

// 将字符串转换成日期
LocalDateTime newDate = ldt.parse(str2,dtf2);
Sytem.out.println(newDate);
}
}

4. 时区的处理

  • 带时区的时间分别为:ZonedDate,ZonedTime,ZonedDateTime; 其中,每个时区都对应着ID; 地区ID都为
    "{区域}/{城市}"的格式,例如,"Asia/Shanghai";
  • ZoneId: 该类中包含了所有的时区信息;
    • getAvailableZoneIds(): 可以获取java8支持的所有时区;
    • of(id): 用指定的时区信息获取 ZoneId 对象;
//测试类
public class TestZone{
@Test
public void test(){

// 查看 java8 支持的所有时区
Set<String> set = ZoneId.getAvailableZoneIds();
set.forEach(System.out::println);

// 获取指定时区的当前时间
LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Europe/London"));
System.out.println(ldt);

// 带时区的时间
ZonedDateTime zdt = ldt.atZone(ZoneId.of("Europe/London"));
System.out.println(zdt);
}
}

5. 可重复注解与类型注解

  • Java8 对注解处理提供了两点改进: 可重复注解及可用于类型的注解;
  • Java8 新增加两个注解的程序元素类型 ElementType.TYPE_USEElementType.TYPE_PARAMETER;
// 自定义注解类
@Repeatable(MyAnnotations.class)
@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation{
String value() default "annotationtest";
}

// 注解容器类
@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotations{
MyAnnotation[] value();
}

// 测试类
public class TestAnnotation{

@Test
public void test(){
Class<TestAnnotation> clazz = TestAnnotation.class;
Method m1 = clazz.getMethod("show");

// 获取 show 方法上的注解
MyAnnotation[] mas = m1.getAnnotationsByType(MyAnnotation.class);

for(MyAnnotation myAnnotation : mas){
System.out.println(myAnnotation.value());
}
}

@MyAnnotation("hello")
@MyAnnotation("world")
public void show(){

}
}


参考资料