Java8 新时间日期API

271 阅读4分钟

Java8 新时间日期API

 使用LocalDate、LocalTime、LocalDateTime

LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息

 注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法

image.png

Instant 时间戳

用于“时间戳”的运算。它是**以Unix元年(传统 的设定为UTC时区1970年1月1日午夜时分)**开始 所经历的描述进行运算

 Duration 和 Period

  • Duration:用于计算两个“时间”间隔
  • Period:用于计算两个“日期”间隔

日期的操纵

  • TemporalAdjuster : 时间校正器
    • 有时我们可能需要获 取例如:将日期调整到“下个周日”等操作。
  • TemporalAdjusters: 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现。
    • 例如获取下个周日:

image.png

解析与格式化

java.time.format.DateTimeFormatter类:该类提供了三种 格式化方法:

  • 预定义的标准格式
  • 语言环境相关的格式
  • 自定义的格式

时区的处理

  • Java8 中加入了对时区的支持,带时区的时间为分别为:
    • ZonedDate、ZonedTime、ZonedDateTime
    • 其中每个时区都对应着 ID,地区ID都为 “{区域}/{城市}”的格式
    • 例如 :Asia/Shanghai 等
    • ZoneId:该类中包含了所有的时区信息
      • getAvailableZoneIds() : 可以获取所有时区时区信息
      • of(id) : 用指定的时区信息获取ZoneId 对象

与传统日期处理的转换

image.png

代码演示

 DateFormatThreadLocal

package com.www.java8.data;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * SimpleDateFormat 上锁, 解决线程问题
 * <p>
 *
 * @author Www
 * <p>
 * 邮箱: 483223455@qq.com
 * <p>
 * 创建时间: 2022/8/13  16:35  星期六
 * <p>
 */
public class DateFormatThreadLocal {
    private static final ThreadLocal<DateFormat> dateFormat = new ThreadLocal<>() {
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };
    
    public static Date convert(String source) throws ParseException {
        return dateFormat.get().parse(source);
    }
    
}


DateTimeFormatterTest

package com.www.java8.data;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * SimpleDateFormat 存在线程安全问题
 * <p>
 *
 * @author Www
 * <p>
 * 邮箱: 483223455@qq.com
 * <p>
 * 创建时间: 2022/8/13  16:26  星期六
 * <p>
 */
public class DateTimeFormatterTest {
    /**
     * 方法入口
     *
     * @param args 参数
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        //        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE;
        
        Callable<LocalDate> callable = () -> LocalDate.parse("2013-09-09", dateTimeFormatter);
        ExecutorService pool = Executors.newFixedThreadPool(10);
        List<Future<LocalDate>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            results.add(pool.submit(callable));
            
        }
        for (Future<LocalDate> result : results) {
            System.out.println(result.get());
        }
        pool.shutdown();
    }
}

 LocalDateTimeTest

package com.www.java8.data;

import org.junit.Test;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Set;

/**
 * <p>
 *
 * @author Www
 * <p>
 * 邮箱: 483223455@qq.com
 * <p>
 * 创建时间: 2022/8/13  16:51  星期六
 * <p>
 */
public class LocalDateTimeTest {
    /**
     * 1、LocalDate 【时间】  LocalTime【日期】  LocalFDateTime 【时间和日期】
     */
    @Test
    public void test1() {
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);
        
        LocalDateTime of = LocalDateTime.of(2020, 8, 13, 10, 30, 20, 30);
        System.out.println("of = " + of);
        LocalDateTime localDateTime1 = localDateTime.plusYears(10);
        System.out.println("localDateTime1 = " + localDateTime1);
        System.out.println("localDateTime.minusYears(5) = " + localDateTime.minusYears(5));
        System.out.println("localDateTime.getYear() = " + localDateTime.getYear());
        System.out.println("localDateTime.getMonthValue() = " + localDateTime.getMonthValue());
        System.out.println("localDateTime.getDayOfMonth() = " + localDateTime.getDayOfMonth());
        System.out.println("localDateTime.getHour() = " + localDateTime.getHour());
        System.out.println("localDateTime.getMinute() = " + localDateTime.getMinute());
        System.out.println("localDateTime.getSecond() = " + localDateTime.getSecond());
        
    }
    
    
    /**
     * 2、Instant :时间戳 ( 以 Unix 元年 : 1970 年 1月1日 00:00:00 某个是时间之间的毫秒数)
     */
    @Test
    public void test2() {
        // 默认获取 utc(格林尼治时间) 时区
        Instant now = Instant.now();
        System.out.println("now = " + now);
        OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime);
        long s = offsetDateTime.toEpochSecond();
        long m = offsetDateTime.toInstant().toEpochMilli();
        System.out.println("s = " + s);
        System.out.println("m = " + m);
        
        
        Instant instant = Instant.ofEpochSecond(1000);
        System.out.println("Instant.MIN = " + Instant.MAX);
        System.out.println("instant = " + instant);
    }
    
    
    /**
     * Duration : 计算两个 "时间" 之间的间隔
     */
    @Test
    public void test3() {
        Instant now = Instant.now();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        Instant now1 = Instant.now();
        Duration between = Duration.between(now, now1);
        System.out.println("between = " + between);
        
        System.out.println("******************************************");
        LocalTime now2 = LocalTime.now();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        LocalTime now3 = LocalTime.now();
        
        System.out.println("Duration.between(now2, now3).toMillis() = " + Duration.between(now2, now3).toMillis());
    }
    
    
    /**
     * Period : 计算两个 "日期" 之间的间隔
     */
    @Test
    public void test4() {
        LocalDate of = LocalDate.of(2022, 8, 9);
        LocalDate of1 = LocalDate.of(22, 6, 9);
        
        Period between = Period.between(of, of1);
        System.out.println("between = " + between);
        System.out.println("between.getYears() = " + between.getYears());
        System.out.println("between.getMonths() = " + between.getMonths());
        System.out.println("between.getDays() = " + between.getDays());
        System.out.println("between.getUnits() = " + between.getUnits());
        
    }
    
    /**
     * TemporalAdjuster :时间矫正器
     */
    @Test
    public void test5() {
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now = " + now);
        LocalDateTime localDateTime = now.withDayOfMonth(8);
        System.out.println("localDateTime = " + localDateTime);
        System.out.println("now.withDayOfMonth(10) = " + now.withDayOfMonth(5));
        
        LocalDateTime with = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
        
        System.out.println("with = " + with);
        
        // 获取下一个工作日
        LocalDateTime with1 = now.with(l -> {
            LocalDateTime l2 = (LocalDateTime) l;
            DayOfWeek dayOfWeek = l2.getDayOfWeek();
            if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
                return l2.plusDays(3);
            } else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
                return l2.plusDays(2);
            } else {
                return l2.plusDays(1);
            }
        });
        System.out.println("with1 = " + with1);
        
    }
    
    /**
     * DateTimeFormatter :格式化时间/日期
     */
    @Test
    public void test6() {
        //        DateTimeFormatter dateTimeFormat=DateTimeFormatter.ISO_DATE;
        //        DateTimeFormatter dateTimeFormat=DateTimeFormatter.ISO_LOCAL_TIME;
        //        DateTimeFormatter dateTimeFormat=DateTimeFormatter.ISO_TIME;
        DateTimeFormatter dateTimeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        String format = dateTimeFormat.format(now);
        System.out.println("format = " + format);
        System.out.println("_________________________");
        LocalDateTime parse = LocalDateTime.parse(format, dateTimeFormat);
        System.out.println(parse);
        
    }
    
    /**
     * ZonedDate ,ZonedTime ,ZonedDateTime
     */
    @Test
    public void test7() {
        Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
        availableZoneIds.forEach(System.out::println);
    }
    
    /**
     *
     */
    @Test
    public void test8() {
        LocalDateTime now = LocalDateTime.now(ZoneId.of("Pacific/Yap"));
        System.out.println("now = " + now);
        LocalDateTime now1 = LocalDateTime.now(ZoneId.of("Pacific/Yap"));
        ZonedDateTime zonedDateTime = now1.atZone(ZoneId.of("Pacific/Yap"));
        ZonedDateTime zonedDateTime1 = now1.atZone(ZoneId.of("Asia/Shanghai"));
        System.out.println(zonedDateTime1);
    }
}

SimpleDateFormatTest

package com.www.java8.data;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * SimpleDateFormat 存在线程安全问题
 * <p>
 *
 * @author Www
 * <p>
 * 邮箱: 483223455@qq.com
 * <p>
 * 创建时间: 2022/8/13  16:26  星期六
 * <p>
 */
public class SimpleDateFormatTest {
    /**
     * 方法入口
     *
     * @param args 参数
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Callable<Date> callable = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                //                return simpleDateFormat.parse("2021-9-9");
                return DateFormatThreadLocal.convert("2021-9-9");
            }
        };
        ExecutorService pool = Executors.newFixedThreadPool(10);
        List<Future<Date>> results = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            results.add(pool.submit(callable));
            
        }
        for (Future<Date> result : results) {
            System.out.println(result.get());
        }
        pool.shutdown();
    }
}