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 } }
计算世界时间的主要标准有:
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()); } }
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); } }
练习:
@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 }
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)); }
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); } }
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); }
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} }