根据个人目前正在编写的《Java核心编程-基础篇》的规划,这部分属于第15章内容,这里沿用了书中的章节编号。另外,因为原文篇幅太长,这里适当做了删减。

15.1、概述

在 Java 8 之前,Java 语言表示时间的方法很简单,几乎都是采用毫秒值来表示时间。

比如获得系统当前时间可以使用以下方法:

long now = System.currentTimeMillis();

System.out.println( now );

这里获取的毫秒值是从 格里高利历 的 1970年1月1日 0点0分0秒0毫秒 至现在所经历的毫秒数。

即使是在 java.util.Date 类的实例 或 java.util.Calendar类的实例中,也仍然是通过毫秒值来表示时间。

因为 java.util.Date 类的实例 或 java.util.Calendar类在设计上的缺陷,

从 Java 8 开始提供了一个全新的包 (java.time ) 来表示时区、日期、时间。

接下来我们将从 Date 和 Calendar 说起,来研究 时期、时间的表示方法 以及 日期格式化 等操作。

15.2、Date 类

Date 类的实例表示特定的瞬间( 精确到毫秒 )。

package java.util;

import java.io.Serializable ;

public class Date implements Serializable, Cloneable, Comparable {

}

Date 类实现了 Serializable 、Cloneable 、Comparable 等接口。

15.2.1、实例字段

Date 类中封装了一个 long 类型的字段,用来保存 Date 实例所表示的时间:

private transient long fastTime;

15.2.2、构造方法

目前还有两个未被废弃的构造方法:

public Date( long millis ) {

fastTime = millis ;

}

public Date() {

this( System.currentTimeMillis() );

}

举例:

import java.util.Date;

public class DateTest1 {

public static void main(String[] args) {

// 构造方法内部将 System.currentTimeMillis() 保存到 fastTime 字段中

Date date = new Date();

System.out.println( date ); // CST : China Standard Time

// 构造方法内部将 -1000L 保存到 fastTime 字段中

Date d = new Date( -1000L );

System.out.println( d );

}

}

注意,输出 date 对象的字符串形式时,CST 表示 China Standard Time ,即中国标准时间。

15.2.3、实例方法

Date 类中绝大多数实例方法都已经被废弃(不赞成使用),仅存的几个可用的实例方法如下:

public long getTime()

获取 Date 实例内部存储的毫秒值。

public void setTime( long time )

设置 Date 实例内部存储的毫秒值。

public String toString()

将当前 Date 实例所存储的毫秒值转换为以下形式的 字符串:

dow mon dd hh:mm:ss zzz yyyy

其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。

public boolean equals( Object obj )

Date 类重写了从 Object 类继承的 equals 方法用于判断当前 Date 实例与另外一个对象是否"相等"。

public boolean after( Date when )

测试 当前 Date 实例 所表示的时间 是否在 指定Date实例 所表示的时间之后。

public boolean before( Date when )

测试 当前 Date 实例 所表示的时间 是否在 指定Date实例 所表示的时间之前。

15.2.3.1、Date实例是可变的

Date 实例 是 【可变的】,在创建 Date 实例后,其内部的 毫秒值 是可以更改的

import java.util.Date;

public class DateTest2 {

public static void main(String[] args) {

long ms = 1000L * 60 * 60 * 24 * 365 * 30 ;

final Date date = new Date( ms );

System.out.println( date );

birthdate.setTime( 1000 );

System.out.println( date );

}

}

15.2.3.2、比较Date实例

Date实例的比较,可以通过 equals 、after 、before 方法来实现:

import java.util.Date;

public class DateTest3 {

public static void main(String[] args) {

long ms = 1000L * 60 * 60 * 24 * 365 * 30 ;

Date first = new Date( ms );

System.out.println( first );

Date second = new Date( ms );

System.out.println( second );

System.out.println( first == second ); // false

// java.utl.Date 类 重写了 从 Object 类继承的 equals 方法

System.out.println( first.equals( second ) ); // true

Date now = new Date();

System.out.println( now.after( first ) ); // true

System.out.println( now.after( second ) ); // true

System.out.println( first.before( now ) ); // true

System.out.println( second.before( now ) ); // true

}

}

不建议使用的比较方法是这样子的:

long firstTime = first.getTime() ;

long secondTime = second.getTime() ;

if( firstTime > secondTime ) {

System.out.println( first + " 晚于 " + second );

}

15.3 Calendar类

Calendar一词表示日历,而 Java 语言中 Calendar 则是一个类,一个声明在 java.util 包中的抽象类。

Calendar 类为特定瞬间日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法

瞬间可用毫秒值来表示,它是距历元的偏移量。

历元(epoch) 是指 格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000 ( 格里高利历 ) 。

15.3.1、日历字段

日历字段是 Calendar 类中声明的用来表示日期时间中指定部分的常量。

常用的日历字段如下:

Calendar.ERA 对应纪元

比如罗马儒略历中的 AD 或 BC ( 中文表示为 公元 或 公元前 )

Calendar.YEAR 对应年份

Calendar.MONTH 对应月份

月份从 0 开始计数,0 表示 January (一月),1 表示 February ( 二月 )

Calendar.DATE 对应月份中的日期

日期从 1 开始计数,有效范围为 1 ~ 31 。

Calendar.HOUR_OF_DAY 对应一天当中的小时

小时从 0 开始计数,有效范围为 0 ~ 23 。

Calendar.MINUTE 对应分钟

分钟从 0 开始计数,有效范围为 0 ~ 59 。

Calendar.SECOND 对应秒

秒数从 0 开始计数,有效范围为 0 ~ 60 。(要注意闰秒)

Calendar.MILLISECOND 对应毫秒

毫秒数从 0 开始计数,有效范围为 0 ~ 999 。

Calendar.DAY_OF_MONTH 对应月份中的日期

日期从 1 开始计数,有效范围为 1 ~ 31 。

Calendar.HOUR 对应上午或下午的小时

小时从 0 开始计数,有效范围为 0 ~ 11 。

Calendar.DAY_OF_WEEK 对应星期

用于指示一个星期中的某天。

该字段可取的值可以是 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY 和 SATURDAY。

Calendar.DAY_OF_YEAR 对应年份中的天数

指示当前年中的天数。一年中第一天的值为 1,最大值为 366 。

15.3.2、获取Calendar实例

15.3.2.1、通过创建子类实例的方式

GregorianCalendar 类是 Calendar 类的子类,

通过创建 GregorianCalendar类的实例即可使用 Calendar 中的方法。

Calendar c = new GregorianCalendar(); // 父类引用 指向 子类对象

System.out.println( c );

15.3.2.2、通过类方法获取

Calendar 类中定义了大量的类方法用于获取 Calendar 实例:

public static Calendar getInstance()

举例:

Calendar c = Calendar.getInstance();

System.out.println( c );

public static Calendar getInstance( TimeZone zone, Locale locale )

举例:

TimeZone zone = TimeZone.getDefault();

Locale locale = Locale.getDefault() ;

Calendar c = Calendar.getInstance( zone , locale );

System.out.println( c );

15.3.3、从 Calendar 实例中获取时间

Calendar 类中声明了以下方法用于从 特定瞬间 中获取 指定日历字段 对应的值:

public int get( int calendarField )

同时在 Calendar 类中声明了以下方法用于获取 Calendar实例所表示的瞬间对应的毫秒值:

public long getTimeInMillis()

举例:

import java.util.Calendar;

import java.util.GregorianCalendar;

public class CalendarTest1 {

public static void main(String[] args) {

// 父类引用 指向 子类对象

Calendar c = new GregorianCalendar();

System.out.println( c );

// 从 c 对应的 Calendar 实例中获取 日历字段 ERA 对应的值

int era = c.get( Calendar.ERA ) ;

System.out.println( era );

int year = c.get( Calendar.YEAR );

System.out.println( year );

// 在西方国家,月份的索引从 零 开始,0 表示 1月 , 11 表示12月

int month = c.get( Calendar.MONTH );

System.out.println( month );

int date = c.get( Calendar.DATE );

System.out.println( date );

int hourOfDay = c.get( Calendar.HOUR_OF_DAY );

System.out.println( hourOfDay );

int minute = c.get( Calendar.MINUTE );

System.out.println( minute );

int second = c.get( Calendar.SECOND );

System.out.println( second );

// 仅仅获取 MILLISECOND 字段对应的值,取值范围为 [ 0 , 1000 )

int millis = c.get( Calendar.MILLISECOND );

System.out.println( millis );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

// 获取 当前的 Calendar 实例所表示的瞬间 对应的毫秒值(距离历元的偏移量)

long ms = c.getTimeInMillis();

System.out.println( ms );

}

}

15.3.4、设置 Calendar 实例

Calendar 类中声明了以下方法用于用于为 指定的 日历字段 设置相应的值:

public void set( int calendarField, int value )

同时也提供了以下方法来批量设置年、月、日、小时、分钟、秒、毫秒等 日历字段 的值

public final void set( int year, int month, int date )

public final void set( int year, int month, int date, int hourOfDay )

public final void set( int year, int month, int date, int hourOfDay, int minute,int second )

需要注意的是,这里的 hourOfDay 与 Calendar.HOUR_OF_DAY对应,表示一天中的小时,取值范围是 0 ~ 23 。

另外,Calendar 类中声明了用于清空所有日历字段取值的方法:

public final void clear()

Calendar 类中也声明了用于清空指定的 日历字段取值的方法:

public final void clear( int calendarField )

举例:

import java.util.*;

public class CalendarTest3 {

public static void main(String[] args) {

// 父类引用 指向 子类对象

Calendar c = new GregorianCalendar();

System.out.println( c );

c.set( Calendar.YEAR , 1996 ); // 公元1996年

c.set( Calendar.MONTH , 0 ); // 月份的索引从 0 开始,0表示1月

c.set( Calendar.DATE , 10 );

c.set( Calendar.HOUR_OF_DAY , 11 );

c.set( Calendar.MINUTE , 45 );

c.set( Calendar.SECOND , 0 );

c.set( Calendar.MILLISECOND , 0 );

System.out.println( c );

System.out.println( c.getTimeInMillis() );

System.out.println( c );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

c.clear(); // 清除所有日历字段的值

System.out.println( c );

// YEAR 、MONTH 、HOUR_OF_DAY 、MINUTE、SECOND

c.set( 0 , 0 , 10 , 11 , 45 , 30 );

c.set( Calendar.MILLISECOND , 100 );

System.out.println( c.getTimeInMillis() );

System.out.println( c );

}

}

15.3.5、将 Calendar 实例转换为 Date类型的实例

Calendar 类中声明了用于将当前的Calendar实例所表示的瞬间转换为Date实例的方法:

public final Date getTime()

举例:

import java.util.*;

public class CalendarTest2 {

public static void main(String[] args) {

// 父类引用 指向 子类对象

Calendar c = new GregorianCalendar();

System.out.println( c );

// java.util.Date 类中的 getTime() 方法可以返回一个毫秒值

// java.util.Calendar 类中的 getTime() 用于返回相应的 Date 实例

Date date = c.getTime(); // 返回 当前 Calendar 实例所表示的瞬间 对应的 Date 实例

System.out.println( date );

}

}

15.3.6、获取任意时间对应的Date实例

截至目前,我们可以借助于 Calendar 实例来获取任意时间对应的 Date 实例,其步骤为

a>、获得 Calendar 实例

b>、清空所有日历字段的值

c>、根据实际需要设置 年月日、时分秒 等日历字段的值

d>、获取 Calendar 实例所表示的瞬间 对应的 Date 实例

举例:

import java.util.*;

public class CalendarTest4 {

public static void main(String[] args) {

TimeZone zone = TimeZone.getDefault();

Locale locale = Locale.getDefault() ;

// 1、获得 Calendar 实例

Calendar c = Calendar.getInstance( zone , locale );

System.out.println( c );

// 2、清空所有日历字段的值

c.clear();

// 3、根据实际需要设置 年月日、时分秒

c.set( 1998 , 10 , 20 , 5 , 30 , 40 );

c.set( Calendar.MILLISECOND , 0 );

// 4、获取 Calendar 实例所表示的瞬间 对应的 Date 实例

Date date = c.getTime();

System.out.println( date );

}

}

在 Java 8 之前,获得 任意的 年月日、时分秒 对应的 Date 实例,可以使用两种方法:

通过将特定格式的字符串解析为Date实例 ( 在 DateFormat 中讲解 )

通过 Calendar 实例来获取

15.4 DateFormat 类

java.text.DateFormat 类提供了用于将日期格式化和解析字符串为Date实例的方法:

public final String format( Date date )

public Date parse(String source) throws ParseException

但是 DateFormat 类是个抽象类,其子类 SimpleDateFormat 是个具体类(非抽象类)。

SimpleDateFormat 类的构造方法:

public SimpleDateFormat()

public SimpleDateFormat( String pattern )

public SimpleDateFormat( String pattern , Locale locale )

public SimpleDateFormat( String pattern , DateFormatSymbols formatSymbols )

其中最常用的是:

public SimpleDateFormat( String pattern )

参数中的 pattern 表示日期的模式。

日期模式的字符串可以使用以下模式字母:

dateformat-pattern.png

比如 yyyy-MM-dd 对应 1996-12-12 。

15.4.1、日期格式化

日期格式化举例:

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Locale;

/**

* 重要: 将 java.util.Date 实例所表示的 【瞬间】 格式化为 【特定模式】的字符串

*/

public class DateFormatTest1 {

public static void main(String[] args) {

long ms = 1000L * 60 * 60 * 24 * 365 * 30 ;

Date birthdate = new Date( ms );

String pattern = "G yyyy年MM月dd日 EEEE HH:mm:ss.SSS" ; // 确定 "日期时间" 的模式

DateFormat df = new SimpleDateFormat( pattern );

String s = df.format( birthdate );

System.out.println( s );

}

}

15.4.2、解析字符串为Date实例

将指定字符串按照特定的模式解析为 Date 实例:

import java.text.DateFormat;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Locale;

import java.util.Scanner;

/**

* 重要: 将 字符串 解析为 java.util.Date 实例

*/

public class DateFormatTest2 {

public static void main(String[] args) {

final String pattern = "yyyy-MM-dd" ;

DateFormat df = new SimpleDateFormat( pattern );

Scanner sc = new Scanner( System.in );// 创建扫描器用户读取用户输入的数据

System.out.println( "请输入一个日期( 格式为 " + pattern + " ,比如 2019-09-01 )" );

String s = sc.nextLine(); // 读取用户输入的整行数据

System.out.println( "你输入的是: " + s );

try {

// 将 字符串 解析为 Date 类型的实例

Date date = df.parse( s ); // 可能抛出 ParseException 异常

System.out.println( date );

long time = date.getTime() ;

System.out.println( time );

} catch ( ParseException e ) {

System.out.println( "你输入的日期格式不符合 " + pattern );

e.printStackTrace();

}

sc.close(); // 关闭扫描器

}

}

15.5 LocalDate类

有鉴于 java.util.Date 类 和 java.util.Calendar 类在设计上的缺陷,从 Java 8 开始,JDK 中新增了 java.time 包,其中定义了大量的用来表示日期、时间的类型。

15.5.1、LocalDate类的设计

java.time.LocalDate 类是一个不可变类,该类是被 final 所修饰,因此该类没有子类。

package java.time;

// 省略 import 语句

public final class LocalDate

implements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {

// 省略其它代码

private final int year; // The year.

private final short month; // The month-of-year.

private final short day; // The day-of-month.

// 省略其它代码

}

在 java.time.LocalDate 类中声明了三个实例字段用来存储 年份、月份、日期:

private final int year;

private final short month;

private final short day;

因为它们都是 final 修饰的,因此一旦创建 LocalDate 实例,其 年份、月份、日期 的值再也不能被更改。

另外,LocalDate 类还声明了以下常量:

public static final LocalDate MIN = LocalDate.of( Year.MIN_VALUE, 1, 1 );

public static final LocalDate MAX = LocalDate.of( Year.MAX_VALUE, 12, 31 );

public static final LocalDate EPOCH = LocalDate.of( 1970, 1, 1 );

从常量命名可知,MAX、MIN 分别表示 LocalDate 所能表示的日期的最大值和最小值。

而 EPOCH 则表示历元对应的日期。

15.5.2、获取 LocalDate 实例

java.time.LocalDate 类提供了许多类方法用于获取 LocalDate 实例,以下是几个常用的方法:

public static LocalDate now()

public static LocalDate of( int year , int month , int dayOfMonth )

public static LocalDate ofYearDay( int year , int dayOfYear )

举例:

import java.time.LocalDate;

public class LocalDateTest1 {

public static void main(String[] args) {

// 通过 LocalDate 类中的 类方法 ( now ) 来获取 LocalDate 实例

LocalDate now = LocalDate.now();

System.out.println( now );

// 通过 LocalDate 类中的 类方法 ( of ) 来获取 LocalDate 实例

LocalDate birthdate = LocalDate.of( 1999 , 12 , 31 );

System.out.println( birthdate );

// 通过 LocalDate 类中的 类方法 ( ofYearDay ) 来获取 LocalDate 实例

LocalDate date = LocalDate.ofYearDay( 2019 , 244 );

System.out.println( date );

}

}

15.5.3、常用实例方法

LocalDate 类中定义了大量的实例方法,其中比较常用的是:

public int getYear() 用于获取年份

public int getMonthValue() 用于获取月份 ( 取值范围是 1 ~ 12 )

public int getDayOfMonth() 用于获取日期 ( 取值范围是 1 ~ 31 )

public DayOfWeek getDayOfWeek() 用于获取星期 ( 返回类型为 DayOfWeek )

public boolean isLeapYear() 用于判断 LocalDate 实例对应的年份是否是闰年

public int lengthOfYear() 用于获取 LocalDate 实例对应的年份的总天数

public int lengthOfMonth() 用于获取 LocalDate 实例对应的月份的总天数

举例:

import java.time.DayOfWeek;

import java.time.LocalDate;

public class LocalDateTest2 {

public static void main(String[] args) {

LocalDate n = LocalDate.now() ;

System.out.println( n.getYear() + "年" );

System.out.println( n.getMonthValue() + "月" );

System.out.println( n.getDayOfMonth() + "日" );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

DayOfWeek day = n.getDayOfWeek();

System.out.println( day );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

boolean leap = n.isLeapYear();

System.out.println( leap );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

System.out.println( n.lengthOfYear() );

System.out.println( n.lengthOfMonth() );

}

}

同时,LocalDate 类中定义了用于比较 LocalDate 实例的方法:

public boolean equals( Object obj )

public boolean isEqual( ChronoLocalDate other )

public boolean isBefore( ChronoLocalDate other )

public boolean isAfter( ChronoLocalDate other )

另外,LocalDate 类还定义了 在指定的 LocalDate 对应的日期基础上 增加或减少 指定时间的方法:

public LocalDate plusYears( long yearsToAdd )

public LocalDate plusDays( long daysToAdd )

public LocalDate plusMonths( long monthsToAdd )

public LocalDate plusWeeks( long weeksToAdd )

举例:

import java.time.DayOfWeek;

import java.time.LocalDate;

public class LocalDateTest3 {

public static void main(String[] args) {

LocalDate n = LocalDate.now(); // 获得当前日期

System.out.println( n );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

// 在 n 所表示的日期基础上减少18年后返回 新的 LocalDate 实例

LocalDate f = n.plusYears( -18 );

System.out.println( f );

System.out.println( n == f );

System.out.println( n.equals( f ) );

System.out.println( n.isEqual( f ) ); // 比较两个 LocalDate 实例是否相等

System.out.println( n.isAfter( f ) );

System.out.println( n.isBefore( f ) );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

// 在 f 所表示的日期基础上增加18年后返回 新的 LocalDate 实例

LocalDate s = f.plusYears( 18 );

System.out.println( s == n );

System.out.println( s.equals( n ) );

System.out.println( s.isEqual( n ) );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

// 在 n 所表示的日期基础上增加 10天 后返回 新的 LocalDate 实例

LocalDate t = n.plusDays( 10 );

System.out.println( t );

// 在 n 所表示的日期基础上增加 5个月 后返回 新的 LocalDate 实例

LocalDate o = n.plusMonths( 5 );

System.out.println( o );

// 在 n 所表示的日期基础上增加 9周 后返回 新的 LocalDate 实例

LocalDate x = n.plusWeeks( 9 );

System.out.println( x );

}

}

15.6 LocalTime 类

15.6.1、LocalTime 类的设计

java.time.LocalTime 类是一个不可变类,该类是被 final 所修饰,因此该类没有子类。

package java.time;

// 省略 import 语句

public final class LocalTime

implements Temporal, TemporalAdjuster, Comparable, Serializable {

// 省略其它代码

private final byte hour ; // The hour.

private final byte minute ; // The minute.

private final byte second ; // The second.

private final int nano ; // The nanosecond.

// 省略其它代码

}

在 java.time.LocalTime 类中声明了四个实例字段用来存储 小时、分钟、秒、纳秒:

private final byte hour ;

private final byte minute ;

private final byte second ;

private final int nano ;

因为它们都是 final 修饰的,因此一旦创建 LocalTime 实例,其中各个字段的值再也不能被更改。

15.6.2、获取 LocalTime 实例

java.time.LocalTime 类提供了许多类方法用于获取 LocalTime 实例,以下是几个常用的方法:

public static LocalTime now()

public static LocalTime of( int hour , int minute )

public static LocalTime of( int hour , int minute , int second )

public static LocalTime of( int hour , int minute , int second , int nanoOfSecond)

举例:

import java.time.LocalTime;

public class LocalTimeTest1 {

public static void main(String[] args) {

LocalTime now = LocalTime.now();

System.out.println( now );

LocalTime f = LocalTime.of( 12,0 );

System.out.println( f );

LocalTime s = LocalTime.of( 12,24 , 36 );

System.out.println( s );

// 1s = 1000ms (毫秒)

// 1ms = 1000us (微秒)

// 1us = 1000ns ( 纳秒 或 毫微秒 )

LocalTime t = LocalTime.of( 12,24 , 36 , 100200300);

System.out.println( t );

}

}

15.6.3、常用实例方法

LocalTime 类中定义了大量的实例方法,其中比较常用的是:

public int getHour() 用于获取小时 (取值范围为 0 ~ 23 )

public int getMinute() 用于获取分钟 (取值范围为 0 ~ 59 )

public int getSecond() 用于获取秒 (取值范围为 0 ~ 59 )

public int getNano() 用于获取纳秒 (取值范围为 0 ~ 999999999 )

举例:

import java.time.LocalTime;

public class LocalTimeTest2 {

public static void main(String[] args) {

LocalTime now = LocalTime.now();

System.out.println( now );

System.out.println( now.getHour() + "时" );

System.out.println( now.getMinute() + "分" );

System.out.println( now.getSecond() + "秒" );

long nano = now.getNano(); // 其返回值为 0 ~ 999999999

long ms = nano / 1000000 ; // 求取毫秒部分的数值( 范围为 0 ~ 999 )

System.out.println( ms + "毫秒" );

long us = nano % 1000000 / 1000 ; // 求取微秒部分的数值( 范围为 0 ~ 999 )

System.out.println( us + "微秒" );

long ns = nano % 1000000 % 1000 ; // 求取纳秒部分的数值( 范围为 0 ~ 999 )

System.out.println( ns + "纳秒" );

}

}

同时,LocalTime 类中定义了用于比较 LocalTime 实例的方法:

public boolean isAfter( LocalTime other )

public boolean isBefore( LocalTime other )

public boolean equals( Object obj )

另外,LocalTime 类还定义了 在指定的 LocalTime 对应的时间基础上 增加或减少 指定时间的方法:

public LocalTime plusHours( long hoursToAdd )

public LocalTime plusMinutes( long minutesToAdd )

public LocalTime plusSeconds( long secondstoAdd )

public LocalTime plusNanos( long nanosToAdd )

举例:

import java.time.LocalTime;

public class LocalTimeTest3 {

public static void main(String[] args) {

LocalTime time = LocalTime.now(); // 获取当前时间

System.out.println( time );

// 在 time 所表示的时间基础上增加 5 小时后返回新的 LocalTime 实例

LocalTime t1 = time.plusHours( 5 );

System.out.println( t1 );

// 在 time 所表示的时间基础上减少 20 分钟 后返回新的 LocalTime 实例

LocalTime t2 = time.plusMinutes( -20 );

System.out.println( t2 );

// 在 time 所表示的时间基础上增加 30 秒 后返回新的 LocalTime 实例

LocalTime t3 = time.plusSeconds( 30 );

System.out.println( t3 );

// 在 time 所表示的时间基础上增加 100200300 纳秒 后返回新的 LocalTime 实例

LocalTime t4 = time.plusNanos( 100200300L );

System.out.println( t4 );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

System.out.println( t1.isAfter( t2 ) );

System.out.println( t2.isBefore( t3 ) );

System.out.println( t3.equals( t4 ) );

}

}

15.7 LocalDateTime类

15.7.1、LocalDateTime 类的设计

java.time.LocalDateTime 类是一个 不可变类,该类是被 final 所修饰,因此该类没有子类。

package java.time;

// 省略 import 语句

public final class LocalDateTime

implements Temporal, TemporalAdjuster, ChronoLocalDateTime,

Serializable {

// 省略其它代码

private final LocalDate date ; // The date part.

private final LocalTime time ; // The time part.

// 省略其它代码

}

在 java.time.LocalDateTime 类中声明了两个实例字段用来存储 日期 和 时间 :

private final LocalDate date ;

private final LocalTime time ;

这里需要注意,不仅仅 date 和 time 字段是 final 修饰的,LocalDate 、LocalTime 类中的实例字段也是 final 修饰的,因此 LocalDateTime 的实例一经创建,其内部的各项取值都是不可更改的。

15.7.2、获取 LocalDateTime 实例

举例:

import java.time.LocalDate;

import java.time.LocalDateTime;

import java.time.LocalTime;

public class LocalDateTimeTest1 {

public static void main(String[] args) {

LocalDateTime datetime = LocalDateTime.now();

System.out.println( datetime );

LocalDateTime first = LocalDateTime.of( 1996 , 7 , 4 , 7 , 30 ) ;

System.out.println( first );

LocalDateTime second = LocalDateTime.of( 1999 , 11 , 20, 6 , 30 , 7 ) ;

System.out.println( second );

LocalDateTime third = LocalDateTime.of( 1999 , 11 , 20, 6 , 30 , 7 , 0 ) ;

System.out.println( third );

LocalDate date = LocalDate.of( 1997 , 7 , 1 );

LocalTime time = LocalTime.of( 10 , 20 );

LocalDateTime fourth = LocalDateTime.of( date , time );

System.out.println( fourth );

}

}

15.7.3、获取日期时间值

从 LocalDateTime 实例中获取 年份、月份、日期 、星期 、小时、分钟、秒、纳秒举例:

import java.time.LocalDateTime;

public class LocalDateTimeTest2 {

public static void main(String[] args) {

LocalDateTime n = LocalDateTime.now();

System.out.println( n.getYear() + "年" );

System.out.println( n.getMonthValue() + "月" );

System.out.println( n.getDayOfMonth() + "日" );

System.out.println( n.getDayOfWeek() );

int hour = n.getHour() ;

int minute = n.getMinute() ;

int second = n.getSecond() ;

int nanos = n.getNano() ;

System.out.println( hour + ":" + minute + ":" + second + "." + nanos );

}

}

15.7.4、增加或减少指定时间

在指定的时间基础之上增加或减少时间 ( 年、月、周、天、时、分、秒、纳秒 )举例:

import java.time.LocalDateTime;

public class LocalDateTimeTest3 {

public static void main(String[] args) {

LocalDateTime dt = LocalDateTime.now();

System.out.println( dt );

LocalDateTime dt1 = dt.plusYears( -3 ); // 减少 3 年

System.out.println( dt1 );

LocalDateTime dt2 = dt.plusMonths( 5 ); // 增加 5 个月

System.out.println( dt2 );

LocalDateTime dt3 = dt.plusWeeks( 10 ); // 增加 10 周

System.out.println( dt3 );

LocalDateTime dt4 = dt.plusDays( 15 ); // 增加 15 天

System.out.println( dt4 );

LocalDateTime dt5 = dt.plusHours( 8 ); // 增加 8 小时

System.out.println( dt5 );

LocalDateTime dt6 = dt.plusMinutes( 30 ); // 增加 30 分钟

System.out.println( dt6 );

LocalDateTime dt7 = dt.plusSeconds( 50 ); // 增加 50 秒

System.out.println( dt7 );

LocalDateTime dt8 = dt.plusNanos( 100300500L ); // 增加 100300500L 纳秒

System.out.println( dt8 );

}

}

15.8、转换

在 Java 8 提供了新的日期时间API后,我们需要在新旧两套日期时间API之间完成转换。

这里仅列举几个常见的类型之间的转换方法。

15.8.1、LocalDate 转 LocalDateTime

在 LocalDate 实例中已经存在年、月、日的数值,因此将 LocalDate 转换到 LocalDateTime 时需要指定相应的时、分、秒、纳秒等数值,借助于 LocalDate 类中提供的 atStartOfDay 、atTime 等方法可以完成该操作。

import java.time.LocalDate;

import java.time.LocalDateTime;

public class LocalDateTest4 {

public static void main(String[] args) {

LocalDate n = LocalDate.now();

System.out.println( n );

LocalDateTime datetime = n.atStartOfDay();

System.out.println( datetime );

LocalDateTime first = n.atTime( 10 , 20 );

System.out.println( first );

LocalDateTime second = n.atTime( 10 , 20 , 30 );

System.out.println( second );

LocalDateTime third = n.atTime( 10 , 20 , 30 , 100200300 );

System.out.println( third );

}

}

15.8.2、LocalTime 转 LocalDateTime

在 LocalTime 实例中已经存在时、分、秒、纳秒等数值,因此将 LocalTime 转换到 LocalDateTime 时需要指定相应的年、月、日等数值,借助于 LocalTime 类中提供的 atDate 方法可以完成该操作。

import java.time.LocalDate;

import java.time.LocalDateTime;

import java.time.LocalTime;

public class LocalTimeTest4 {

public static void main(String[] args) {

LocalTime time = LocalTime.now() ;

System.out.println( time );

LocalDate date = LocalDate.of( 2019 , 10 , 10 );

LocalDateTime dateTime = time.atDate( date );

System.out.println( dateTime );

}

}

15.8.3、LocalDateTime 转 LocalDate 或 LocalTime

我们已经知道在 LocalDateTime 实例中封装了一个 LocalDate 实例和一个 LocalTime 实例,因此可以通过 LocalDateTime 提供的方法直接获取相应的 LocalDate 实例和 LocalTime 实例。

import java.time.LocalDate;

import java.time.LocalDateTime;

import java.time.LocalTime;

public class LocalDateTimeTest4 {

public static void main(String[] args) {

LocalDateTime datetime = LocalDateTime.now();

System.out.println( datetime );

LocalDate date = datetime.toLocalDate();

System.out.println( date );

LocalTime time = datetime.toLocalTime();

System.out.println( time );

}

}

15.8.4、Date 转 LocalDateTime

将 java.util.Date 类型的实例转换成 LocalDateTime 类型实例的方法不止一种,这里介绍其中一种实现方法,并通过举例,简单了解一下 Instant 、 ZoneId 、ZonedDateTime 三个类的作用。

以下举例说明将 java.util.Date 类型的实例转换为 java.time.LocalDate 类型的实例:

import java.time.*;

public class TransformTest1 {

public static void main(String[] args) {

final long ms = 1000L * 60 * 60 * 24 * 365 * 30 ;

java.util.Date date = new java.util.Date( ms );

System.out.println( date );

System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

// 根据指定的 java.util.Date 实例获取与之对应的 java.time.Instant 实例

Instant instant = date.toInstant();

// 根据时区编号(ID)获取相应的 java.time.ZoneId 实例

ZoneId zone = ZoneId.of( "Asia/Shanghai" ) ;

// 根据 Instant 实例获取带有时区的日期时间对象( ZonedDateTime 实例 )

ZonedDateTime zonedDateTime = instant.atZone( zone );

// 根据 带有时区的日期时间对象 ( ZonedDateTime 实例 ) 获取 LocalDateTime 实例

LocalDateTime datetime = zonedDateTime.toLocalDateTime() ;

System.out.println( datetime );

// 根据 带有时区的日期时间对象 ( ZonedDateTime 实例 ) 获取 LocalDate 实例

LocalDate d = zonedDateTime.toLocalDate();

System.out.println( d );

// 根据 带有时区的日期时间对象 ( ZonedDateTime 实例 ) 获取 LocalTime 实例

LocalTime t = zonedDateTime.toLocalTime();

System.out.println( t );

}

}

以上举例,实际上完成了以下几种转换:

将 java.util.Date 实例 转换为 java.time.LocalDateTime 实例

将 java.util.Date 实例 转换为 java.time.LocalDate 实例

将 java.util.Date 实例 转换为 java.time.LocalTime 实例

15.8.5、LocalDateTime转 Date

在了解将 java.util.Date 实例转换为 java.time.LocalDateTime 实例的基础上,我们可以实现将 java.time.LocalDateTime 实例转换为 java.util.Date 实例 ( 仅列举一种方法 )。

import java.time.*;

import java.util.Date;

public class TransformTest2 {

public static void main(String[] args) {

LocalDateTime datetime = LocalDateTime.of( 1999 , 11 , 22 , 6 , 30 , 7 );

// 获取系统平台默认的时区编号对应的 java.time.ZoneId 实例

ZoneId zone = ZoneId.systemDefault() ;

// 根据 LocalDateTime 实例获取带有时区的日期时间对象 ( ZonedDateTime 实例 )

ZonedDateTime zonedDateTime = ZonedDateTime.of( datetime , zone ) ;

// 根据 带有时区的日期时间对象 ( ZonedDateTime 实例 ) 获取与其相应的 Instant 实例

Instant instant = Instant.from( zonedDateTime );

// 使用 java.util.Date 类提供的 from 方法获取与指定 Instant 实例对应的 Date 实例

java.util.Date date = Date.from( instant );

System.out.println( date );

}

}

java中定义一个时间_Java中的日期和时间相关推荐

  1. java if 定义变量赋值_Java中简单的操作(if语句、常用操作符、switch语句、变量赋值等)...

    ---------------------if语句介绍--------------------------------------------------- class IfDemo { public ...

  2. java定义一个静态类_Java中的静态类

    在java中有类似的静态类的类吗? 静态类的定义是什么.静态类的所有方法都需要是静态的吗? 是否需要相反的方式,如果一个类包含所有的静态方法,类应该是静态的? 静态类有什么好处? 回答: Java有静 ...

  3. java如何枚举定义一个数组_Java中如何将字符枚举类变成一个数组

    ( light. class ); currenummap.put(light. red , " 红灯 " ); currenummap.put(light. green , &q ...

  4. java去除字符串中最后一个字符_java中字符串如何去除最后一个字符方法

    java中字符串如何去除最后一个字符方法. 方法有很多.不过如果只是个测试,那哪种都可以. 最简单易懂的方法 利用substring()与length() String str = "abc ...

  5. java显示时间_Java如何显示日期和时间?

    在Java中,如何显示当前日期和时间? 此示例显示如何使用Formatter类的fmt.format()方法和Calendar类的Calendar.getInstance()方法来显示当前日期和时间. ...

  6. java取上一个月_Java获取指定日期前一月(年)或后一月(年)

    /** * 获取指定月的前一月(年)或后一月(年) * @param dateStr * @param addYear * @param addMonth * @param addDate * @re ...

  7. java 整型数组定义_在Java中定义一个具有10个元素的整型数组a的语句是:___

    在Java中定义一个具有10个元素的整型数组a的语句是:___ 答: int [] arr = new int[10] 在借贷记账法下() 答:在账户结构上,"借"和"贷 ...

  8. java语言中修饰一个常量_接口中定义一个常量所用的修饰符有: (5.0分)_学小易找答案...

    [判断题]Java中的接口不允许被继承 (5.0分) [单选题]下列程序的输出结果是( ) public class Ex_36{ public static void main(String arg ...

  9. Java编程定义一个数组,输出数组中的最大值与最小值

    package com.pzhu.demo;public class MaxMin {//Java编程定义一个数组,输出数组中的最大值和最小值public static void main(Strin ...

  10. 39.在Java中定义一个不做事且没有参数的构造方法的作用?

    1 在Java中定义一个不做事且没有参数的构造方法的作用 Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会 调用父类中"没有参数的构造方法&quo ...

最新文章

  1. Android:字节跳动必备Context原理解析及使用
  2. TensorFlow配置日志等级
  3. zookeeper(一):功能和原理
  4. 新闻视频 36:整合首页 用到 Repeater 主要用gridview /gridview去掉边框用到 BorderWidth=”0” inner join和 left...
  5. tkinter 菜单添加事件_Python+tkinter设置Label字体、字号、样式、对齐方式、鼠标形状、响应鼠标事件...
  6. CAN总线知识点概述
  7. java postgresql json_java – 将PostgreSQL JSON列映射到Hibernate值类...
  8. leetcode 77. 组合 思考分析
  9. IOS之NSValue整理
  10. Linux中的进程调度(六)
  11. ASP.NET学习笔记1—— MVC
  12. Unity3D脚本中文系列教程(十四)
  13. 百套Java实战项目
  14. java 基础——函数(方法)
  15. Autodesk 3ds Max 2011 / 3ds Max Design 2011)简体中文版 32位+64位
  16. Halcon标定系列(1):实现机械手手眼标定项目介绍、9点标定
  17. python设置excel单元格数据类型为文本_Python xlwt设置excel单元格字体及格式
  18. springboot+vue公务员考试信息管理系统java
  19. cad2017单段线_CAD将线段分成多段线的方法步骤
  20. angular数据绑定

热门文章

  1. ubuntu从tty终端模式返回到图形桌面
  2. 如何生成高效、兼容性好的Poco定位脚本
  3. java 调用支付宝支付接口
  4. LMS与RLS算法学习笔记
  5. 使用MMDetection训练自己的数据集
  6. ubuntu 安装jdk 1.8
  7. 写给Krpano小白们的最最最入门级教程(一)
  8. linux网络hack用法之onlink路由
  9. Flask实现Json数据存库和收藏功能
  10. 微信h5页面图片预览