Java日期时间API

JDK8之前日期时间API

1 - java.lang.System类

System类提供的public static long currentTimeMillis()用来返回当前时 间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。

1 此方法适于计算时间差。

public class DateAPI2 {
    // 1.System类中的currentTimeMillis() 用来返回当前时 间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
    @Test
    public void test1(){
        long time = System.currentTimeMillis(); // 时间戳
        System.out.println(time); // 1591841788517
    }
}
System.currentTimeMillis()

计算世界时间的主要标准有:

  1 UTC(Coordinated Universal Time)

  2 GMT(Greenwich Mean Time)

  3 CST(Central Standard Time)

2 - java.util.Date类 

表示特定的瞬间,精确到毫秒

构造器:

  1 Date():使用无参构造器创建的对象可以获取本地当前时间。

  2 Date(long date)

常用方法:

  1 getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象 表示的毫秒数。

  2 toString():把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat),zzz是时间标准。

  3 其它很多方法都过时了

package com.lzh.java2;

import org.junit.Test;
import java.util.Date;

/*
JDK 8之前日期和时间的API测试
 */
public class DateAPI2 {
    // 1.System类中的currentTimeMillis() 用来返回当前时 间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差
    @Test
    public void test1(){
        long time = System.currentTimeMillis(); // 时间戳
        System.out.println(time); // 1591841788517
    }
    @Test
    public void test2(){
        /*
        java.util.Date类 --> 子类(java.sql.Date)
        1.两个构造器的使用
        2.两个方法的使用
            >toString() 显示当前的、年、月、日、时、分、秒
            >getTime() 获取当前Date对象对应的毫秒数。(时间戳)
        3.java.sql.Date对应着数据库中日期类型的变量
            >如何实例化
                java.sql.Date date = new java.sql.Date(时间戳);
            >如何将java.util.Date对象转化为sql.Date类
                Date date1 = new java.sql.Date(1591844799797L);
                java.sql.Date date2 = (java.sql.Date) date1;
         */

        // 构造器1:Date() --> 创建一个对应当前时间的Date对象
        Date time = new Date();
        System.out.println(time.toString()); // Thu Jun 11 11:06:39 CST 2020
        System.out.println(time.getTime()); // 1591844799797

        // 构造器2:创建指定毫秒数的Date对象
        Date time1 = new Date(1591844799797l);
        System.out.println(time1.toString());

    }
}
View Code

3 - java.text.SimpleDateFormat类

1 Date类的API不易于国际化,大部分被废弃了,java.text.SimpleDateFormat 类是一个不与语言环境有关的方式来格式化和解析日期的具体类。

2 它允许进行格式化:日期→文本、解析:文本→日期

3 格式化:

  ① SimpleDateFormat() :默认的模式和语言环境创建对象

  ② public SimpleDateFormat(String pattern):该构造方法可以用参数pattern 指定的格式创建一个对象,该对象调用:

  ③ public String format(Date date):方法格式化时间对象date

4 解析:

  ① public Date parse(String source):从给定字符串的开始解析文本,以生成 一个日期。

package com.lzh.java2;

import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
SimpleDateFormat的使用:SimpleDateFormat对日期Date类的格式化和解析
1-格式化:日期 --> 字符串
2-解释(格式化的逆过程):字符串 --> 日期
 */
public class DateAPI {
    @Test
    public void test1() throws ParseException {
        // SimpleDateFormat的实例化
        SimpleDateFormat date = new SimpleDateFormat();

        // 格式化:日期 --> 字符串
        Date time = new Date();
        // System.out.println(time);
        System.out.println(date.format(time));

        // 解释(格式化的逆过程):字符串 --> 日期
        String string = "2020/6/11 下午6:37"; // 对字符串格式有要求,有局限性
        Date date1 = date.parse(string);
        System.out.println(date1);

        // 指定参数对SimpleDateFormat进行实例化(按照指定的方式格式化和解析)
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        // 格式化:日期 --> 字符串
        System.out.println(dateFormat.format(time));

        // 解析:字符串 --> 日期 要求字符串必须是符合SimpleDateFormat识别的格式(通过构造器参数体现) 否则抛异常
        Date date2 = dateFormat.parse("2020-06-11 06:57:56"); // 匹配对应的参数
        System.out.println(date2);
    }
}
SimpleDateFormat的使用

 练习:

    @Test
    public void test2() throws ParseException {
        // 练习1:字符串"2020-06-08"转换为java.sql.Date
        String date = "2020-06-08";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date d = simpleDateFormat.parse(date);
        java.sql.Date dates = new java.sql.Date(d.getTime());

        System.out.println(dates.getClass()); // class java.sql.Date
        System.out.println(dates); // 2020-06-08
    }
View Code

4 - java.util.Calendar(日历)类

1 Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能。

2 获取Calendar实例的方法

  ① 使用Calendar.getInstance()方法

  ② 调用它的子类GregorianCalendar的构造器。

3 一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想 要的时间信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、 MINUTE、SECOND  public void set(int field,int value)

  ① public void add(int field,int amount)

  ② public final Date getTime()

  ③ public final void setTime(Date date)

4 注意:

  ① 获取月份时:一月是0,二月是1,以此类推,12月是11

  ② 获取星期时:周日是1,周二是2 , 。。。。周六是7

 

    @Test
    public void test3(){
        // Calender日历类(抽象类)的使用
        // 1-实例化
        // 方式1:创建其子类(GregorianCalendar)的对象
        // 方式2:调用其静态方法getInstance()

        GregorianCalendar calendar1 = new GregorianCalendar();
        System.out.println(calendar1.getClass()); // class java.util.GregorianCalendar

        Calendar calendar2 = Calendar.getInstance();
        System.out.println(calendar2.getClass()); // class java.util.GregorianCalendar

        // 2-常用方法   get() / set() / add() / getTime() / setTime()
        int days = calendar1.get(Calendar.DAY_OF_MONTH);
        System.out.println(days);
        System.out.println(calendar2.get(Calendar.DAY_OF_YEAR));
    }
Calendar日历类的使用

JDK8中新日期时间API

1 - 新日期时间API出现的背景

如果我们可以跟别人说:“我们在1502643933071见面,别晚了!”那么就再简单不 过了。但是我们希望时间与昼夜和四季有关,于是事情就变复杂了。JDK 1.0中包含了 一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用 了。而Calendar并不比Date好多少。它们面临的问题是:

可变性:像日期和时间这样的类应该是不可变的。

偏移性:Date中的年份是从1900开始的,而月份都从0开始。

格式化:格式化只对Date有用,Calendar则不行。 此外,它们也不是线程安全的;不能处理闰秒等。

 

总结:对日期和时间的操作一直是Java程序员最痛苦的地方之一。

2 - 新时间日期API介绍

1 第三次引入的API是成功的,并且Java 8中引入的java.time API 已经纠正了 过去的缺陷,将来很长一段时间内它都会为我们服务。

2 Java 8 吸收了 Joda-Time 的精华,以一个新的开始为 Java 创建优秀的 API。 新的 java.time 中包含了所有关于本地日期(LocalDate)、本地时间 (LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime) 和持续时间(Duration)的类。历史悠久的 Date 类新增了 toInstant() 方法, 用于把 Date 转换成新的表示形式。这些新增的本地化时间日期 API 大大简 化了日期时间和本地化的管理。

   

  java.time – 包含值对象的基础包

  java.time.chrono – 提供对不同的日历系统的访问

  java.time.format – 格式化和解析时间和日期

  java.time.temporal – 包括底层框架和扩展特性

  java.time.zone – 包含时区支持的类

 

说明:大多数开发者只会用到基础包和format包,也可能会用到temporal包。因此,尽 管有68个新的公开类型,大多数开发者,大概将只会用到其中的三分之一。

3 - LocalDate类、LocalTime类、LocalDateTime类

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

  1 LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。

  2 LocalTime表示一个时间,而不是日期。

  3 LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。

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

 

package com.lzh.java2;

import org.junit.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/*
jdk 8中日期时间API测试
LocalDate、LocalTime、LocalDateTime类的使用
说明:
    1. LocalDateTime相较于LocalDate、LocalTime。使用频率要高。
    2. 类似于Calendar类
 */
public class JDK8DateTest {
    @Test
    public void test1(){
        // now() 获取当前日期、时间 时间+日期
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDate); // 2020-06-12
        System.out.println(localTime); // 08:19:31.014472200
        System.out.println(localDateTime); // 2020-06-12T08:19:31.014472200

        // of() 设置指定的年、月、日、时、分、秒。没有偏移量
        LocalDateTime time = localDateTime.of(2020,02,12,8,58);
        System.out.println(time);

        // getXxx() 获取属性
        System.out.println(localDateTime.getDayOfMonth());
        System.out.println(localDateTime.getDayOfWeek());
        System.out.println(localDateTime.getDayOfYear());

        // WithXxxx() 设置相关属性
        // 体现不可变性,只返回改变以后的值,原来的值没有改变
        LocalDateTime time1 = localDateTime.withDayOfMonth(12);



    }
}
LocalDate、LocalTime、LocalDateTime类的使用

4 - 瞬时-Instant类

1 Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间 戳。

2 在处理时间和日期的时候,我们通常会想到年,月,日,时,分,秒。然而,这只是 时间的一个模型,是面向人类的。第二种通用模型是面向机器的,或者说是连 续的。在此模型中,时间线中的一个点表示为一个很大的数,这有利于计算机 处理。在UNIX中,这个数从1970年开始,以秒为的单位;同样的,在Java中, 也是从1970年开始,但以毫秒为单位。

3 java.time包通过值类型Instant提供机器视图,不提供处理人类意义上的时间 单位。Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。 概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒 数。因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。

4 (1 ns = 10-9 s)   1秒 = 1000毫秒 =10^6微秒=10^9纳秒

 

    @Test
    public void test2(){
        // Instant的使用
        // 类似于 java.util.Date类
        // now() 静态方法,返回默认UTC时区的Instant类的对象
        Instant instant = Instant.now();
        System.out.println(instant); // 2020-06-12T01:23:27.637392500Z 有时差,并不是本地时间

        // atOffset() 结合即时的偏移来创建一个 OffsetDateTime
        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8)); // 添加时间偏移量
        System.out.println(offsetDateTime); // 输出本地时间,没有时差

        // toEpochMilli() 获取时间戳(1970年1月1日0时0分0秒(UTC)开始的秒数)
        long t = instant.toEpochMilli();
        System.out.println(t); // 1591925579945

        // ofEpochMilli(long epochMilli) 静态方法,返回在1970-01-01 00:00:00基础上加上指定毫秒 数之后的Instant类的对象
        Instant instant1 = Instant.ofEpochMilli(t);
        System.out.println(instant1);
    }
Instant的使用

5 - DateTimeFormatter 类

    @Test
    public void test3(){
        /*
        DateTimeFormatter类的使用
        作用:格式化或解析日期、时间,类似于SimpleDateFormat类
        实例化:
            方式1 预定义的标准格式。如: ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
            方式2 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
            方式3 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
         */
        // 方式1 预定义的标准格式。如: ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        // 格式化:时间 --> 字符串
        LocalDateTime localTime = LocalDateTime.now();
        String time1 = dateTimeFormatter.format(localTime);
        System.out.println(localTime);
        System.out.println(localTime.getClass()); // class java.time.LocalDateTime

        System.out.println(time1); // 2020-06-12T09:54:34.7123926
        System.out.println(time1.getClass()); // class java.lang.String

        // 解析:字符串 --> 时间
        String time2 = "2020-06-12T09:54:34.7123926";
        TemporalAccessor dateTime = dateTimeFormatter.parse(time2);
        System.out.println(dateTime); // {},ISO resolved to 2020-06-12T09:54:34.712392600

        // 方式2 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG)
        // FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT :适用于LocalDateTime
        DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
        LocalDateTime localDateTime = LocalDateTime.now();
        // 格式化
        System.out.println(dateTimeFormatter1.format(localDateTime)); // 2020/6/12 上午10:35

        DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
        LocalDateTime localDateTime1 = LocalDateTime.now();
        System.out.println(dateTimeFormatter2.format(localDateTime1)); // 2020年6月12日星期五

        // 方式3 自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)
        DateTimeFormatter dateTimeFormatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        // 格式化
        System.out.println(dateTimeFormatter3.format(LocalDateTime.now())); // 2020-06-12 10:52:16

        // 解析
        TemporalAccessor temporalAccessor = dateTimeFormatter3.parse("2020-06-12 10:52:16");
        System.out.println(temporalAccessor);
        // {SecondOfMinute=16, HourOfAmPm=10, MinuteOfHour=52, MicroOfSecond=0, MilliOfSecond=0, NanoOfSecond=0},ISO resolved to 2020-06-12}

    }
DateTimeFormatter类的使用

 

posted @ 2020-06-11 10:01  赖正华  阅读(130)  评论(0编辑  收藏  举报