Java8中新的日期时间API

文章目录

  • 什么是新的日期时间API?
  • 为什么要使用它?
  • 如何使用?

什么是新的日期时间API?

Java8新引入了一个java.time包,该包下包含了Java8中对于日期时间处理的另一种解决方案。

为什么要使用它?

在Java8前的版本中,日期时间处理只能通过Date Calender SimpleDateFormat等原生API处理,这种处理方式一直被人吐槽,在某次Tiago Fernandez 举行的Java最烂API评选中荣获第二名,下图为赛情
Java8中新的日期时间API_第1张图片
图片引用于Tiago Fernandez
仔细一想,Java8前原生日期时间处理API确实有点反人类,例如想使用Date保存今天日期时

public static void main(String[] args) {
    Date date = new Date(2020, 6, 12);
    System.out.println(date);
}

我们想的应该是创建一个Date对象用来保存2020年6月12日这个日期,但看到输出之后,发现事情并没有我们想的那么简单
在这里插入图片描述
Date对象确实建好了,但year我明明给的2020,却变成3920,month明明给的是6,却最后却保存为了7。
当然还有一种原生日期API中还有一种日期保存的解决方案-Calender,其公有静态方法getInstance可以获取一个保存当前日期的日历对象
话不多说,先上代码

public static void main(String[] args) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DAY_OF_MONTH);
    System.out.println(new StringBuilder("").append(year).append("/").append(month).append("/").append(day));
}

我们来看看它的输出
在这里插入图片描述
由于Calender默认的MONTH是从0开始计时的,所以所以6月Calender中用5表示,这不一致有没有让你抓狂?我就想用一个Calender对象保存今天的日期,调用getInstance后居然还需要我手动修改其MONTH值?
当然SimpleDateTimeFormat肯定也跑不了,不知道你们有没有看过其源码,如果看过那你就会发现,这是一个线程不安全的类,所以说在多线程的环境下,使用时还给考虑会不会出现线程安全问题。如果会,还给额外写大量避免线程安全的代码。这个问题让本就不富裕的家庭又是雪上加霜。
而在Java8中这些问题都得到了解决。

如何使用?

Java8中新的日期时间API_第2张图片
上图为Java8中java.time包下的类,该包下的类都有个特点,那就是被final修饰,且线程安全,本篇主要对其中最关键的几个类进行讲解
Clock——用于获取指定时区的当前日期
简单使用

public class Main {
    public static void main(String[] args) {
        Clock clock = Clock.systemUTC();//获取当前时钟,使用UTC时区转换为日期和时间。同System.currentTimeMillis()
        Clock clock2 = Clock.systemDefaultZone(); //获取当前时钟,使用系统默认时区转换为日期和时间
        Clock clock3 = Clock.system(ZoneId.of("Asia/Shanghai")); //获取当前时钟,使用参数中自定义的时区转换为日期和时间
        Clock clock4 = Clock.fixed(Instant.now(), ZoneId.of("Europe/Paris"));//返回以第一参数作为时间戳,第二参数作为时区的时钟
        Clock clock5 = Clock.offset(Clock.systemUTC(), Duration.ofSeconds(2)); //返回距离第一参数时钟对象第二参数持续时间的时钟
        System.out.println(clock.millis());
        System.out.println(clock2.millis());
        System.out.println(clock3.millis());
        System.out.println(clock4.millis());
        System.out.println(clock5.millis());
    }
}

控制台输出
在这里插入图片描述
Instant——时间戳,但区别于原生API的Date所维护的fastTime不同,fastTime仅精确到毫秒,而Instant可以精确到纳秒的,其内部是由两个Long字段组成,第一个部分保存的是1970年1月1日开始到现在的秒数,第二部分保存的是纳秒数,值得一提的是第二部分的值永远不会超过999,999,999
简单使用

public class Main {
    public static void main(String[] args) {
        Instant instant1 = Instant.now();//同Instant.now(Clock.systemUTC())
        Instant instant2 = Instant.now(Clock.system(ZoneId.of("Asia/Shanghai")));//获取参数时钟对象时间戳
        System.out.println(instant1.getEpochSecond());//精确到秒
        System.out.println(instant1.toEpochMilli());//精确到毫秒
        System.out.println(instant1.getNano());//获取当前时间戳的纳秒值
        System.out.println(instant2.getEpochSecond());//精确到秒
        System.out.println(instant2.toEpochMilli());//精确到毫秒
        System.out.println(instant2.getNano());//获取当前时间戳的纳秒值
    }
}

LocalDate——不含时间的日期
LocalTime——不含日期的时间
LocalDateTime——包含日期和时间
简单使用

public class Main {
    public static void main(String[] args) {
        //使用系统默认时区创建当前日期时间对象
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);
        //使用自定义时区创建日期时间对象
        localDateTime = LocalDateTime.now(ZoneId.of("Asia/Kolkata"));
        System.out.println(localDateTime);
        //使用LocalDate和LocalTime对象创建日期时间对象
        localDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.now());
        System.out.println(localDateTime);
        //使用自定义时间创建日期时间对象
        localDateTime = LocalDateTime.of(2020, 6, 12, 12, 12, 12);
        System.out.println(localDateTime);
        //通过时间戳获取时间
        localDateTime = LocalDateTime.ofEpochSecond(10000, 0, ZoneOffset.UTC);
        System.out.println(localDateTime);
        //日期时间格式化
        String date = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd mm:ss"));
        System.out.println(date);
        //通过日期字符串创建日期时间对象
        localDateTime = LocalDateTime.parse("2020-06-12T12:12:12");
        System.out.println(localDateTime);
        //获取该日期时间对象所对应的年份
        System.out.println(localDateTime.getYear());
        //获取该日期时间对象所对应的月份
        System.out.println(localDateTime.getMonth());
        //获取该日期时间对象所相对于年的天数
        System.out.println(localDateTime.getDayOfYear());
        //获取该日期时间对象所相对于月的天数
        System.out.println(localDateTime.getDayOfMonth());
        //获取该日期时间对象所相对于星期的天数
        System.out.println(localDateTime.getDayOfWeek());
        //获取该日期时间对象所对应的时
        System.out.println(localDateTime.getHour());
        //获取该日期时间对象所对应的分
        System.out.println(localDateTime.getMinute());
        //获取该日期时间对象所对应的时秒
        System.out.println(localDateTime.getSecond());
        //获取该日期时间对象所对应的纳秒
        System.out.println(localDateTime.getNano());

    }
}

ZonedDateTime——包含时区,日期和时间
ZonedDateTime与之前三个类的使用差不多,不过其parse方法可自定义时区

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zonedDateTime = ZonedDateTime.parse("2020-06-12T12:12:12Z[Europe/Paris]");
        System.out.println(zonedDateTime);

    }
}

你可能感兴趣的:(JavaSE,java)