14、Date and Time (日期和时间)

该博客围绕Java日期和时间处理展开,介绍了java.util.Date、java.util.Calendar等类的字段、构造、方法及缺点,还涉及时区、地区相关内容。同时给出多个代码示例,帮助理解这些类的设计、使用及相互转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章目录

(一)Note

1、java.util.Date

1.1、字段
  • private transient long fastTime;
  • 利用fastTime字段来存储 毫秒值
1.2、构造
  • public Date()
  • public Date(long date)
1.3、类方法
  • public static Date from(Instant instant)
1.4、实例方法
  • public long getTime()

  • public void setTime(long time)

  • public boolean equals(Object o)

    • Date类重写后的equals方法用于比较两个Date实例是否相等
    • 实际上在Date类重写后的equals方法内部 比较的是 两个Date实例中所保存的毫秒值
  • public boolean before(Date when)

    • 当当前Date实例 早于 参数指定的Date实例 时返回true
  • public boolean after(Date when)

    • 当当前Date实例 晚于 参数指定的Date实例 时返回true
  • public Instant toInstant()

1.5、子类
  • java.sql.Date
  • java.sql.Time
  • java.sql.Timestamp
1.6、缺点
  • Date类不是最终类

  • Date类的实例是可变的

  • 不是线程安全的

  • 设计不够友好

    • 比如无法快速获得指定年月日对应的Date实例

2、java.util.Calendar

2.1、日历字段
  • public static final int YEAR = 1 ;
  • public static final int MONTH = 1 ;
  • public static final int DATE = 1 ;
  • public static final int HOUR = 1 ;
  • public static final int HOUR_OF_DAY = 1 ;
  • public static final int MINUTE = 1 ;
  • public static final int SECOND = 1 ;
  • public static final int MILLISECOND = 1 ;
2.2、类方法
  • public static Calendar getInstance()
  • public static Calendar getInstance(TimeZone tz , Locale locale)
2.3、实例方法
  • public int get(int field)
  • public int set(int field , int value)
  • public int set(int year , int month , int date)
  • public int set(int year , int month , int date , int hourOfDay , int minute)
  • public int set(int year , int month ,int date , int hourOfDay , int minute , int second)
  • public final void clear()
  • public final void clear(int field)
  • public final Date getTime()
  • public final void setTime(Date date)
  • public long getTimeInMillis()
  • public void setTimeZone(TimeZone value)
  • public TimeZone getTimeZone()
  • public boolean before(Object when)
  • public boolean after(Object when)
  • public boolean equals(Object obj)
2.4、缺点
  • Calendar类是抽象类,因此它不是最终类,类的实例是可变的
  • 线程不安全
  • 通过日历字段来设置Calendar实例所表示的瞬间 比较繁琐
  • 相对于Date类来说设计上较友好

3、时区和地区

  • java.util.TimeZone表示 时区

    • public static TimeZone getDefault()
    • public static TimeZone getTimeZone(String ID)
  • java.util.Locale表示 国家/地区

    • 构造
      • public Locale (String language)
      • public Locale (String language , String country)
    • 类方法
      • public static Locale getDefault()
    • 实例方法
      • public final String getDisplayCountry()
      • public Strign getDisplayCountry(Locale inLocale)

4、java.text.DateFormat

  • 类方法

  • 实例方法

  • 子类

    • java.text.SimpleDateFormat(日期时间模式)
5、java.time.ZoneId
  • 类方法

    • public static ZoneId systemDefault()
    • public static Set getAvailableZoneIds()
    • public static ZoneId of(String zoneId)
  • 实例方法

    • public String getDisplayName(TextStyle style , Locale locale)

6、java.time.LocalDate

  • 设计

    • LocalDate类是个最终类
    • LocalDate类的实例是不可变的
      • private final int year;
      • private final short month;
      • private final short date;
    • LocalDate类的所有构造都是私有的
  • 常量

  • 类方法

    • public static LocalDate now()
    • public static LocalDate of(int year , int month , int dayOfMonth)
    • public static LocalDate ofYearDay(int year , int dayOfYear)
  • 实例方法

    • public LocalDateTime atStartOfDay()
    • public LocalDateTime atTime(int hour , int minute)
    • public LocalDateTime atTime(int hour , int minute ,int second)
    • public LocalDateTime atTime(int hour ,int minute ,int second int nano)
    • public LocalDateTime atTime(LocalTime time)

7、java.time.LocalTime

  • 设计

    • LocalTime是个最终类
    • LocalTime类的实例是不可变的
      • private final byte hour;
      • private final byte minute;
      • private final byte second;
      • private final int nano;
    • LocalTime类的所有构造都是私有的
  • 常量

  • 类方法

    • public static LocalTime now()
    • public static LocalTime now(ZoneId zone)
    • 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 nano)
  • 实例方法

8、java.time.LocalDateTime

  • 设计
    • LocalDateTime类是最终类
    • LocalDateTime类的实例是不可变的
      • private final LocalDate date;
      • private final LocalTime time;
    • LocalDateTime类的所有构造都是私有的
  • 类方法
  • 实例方法

9、java.time.ZonedDateTime

  • 类方法
    • public static ZonedDateTime of(LocalDateTime localDateTime , ZoneId zone)
    • public static ZonedDateTime of(LocalDate date , LocalTime time , ZoneId zone)

10、java.time.Instant

  • 类方法
    • public static Instant from (TemporalAccssor temporal)
  • 实例方法
    • public ZonedDateTime atZone (ZoneId zone)

(二)Code

1、理解java.util.Date类的设计

MyDate.java
package cn.edu.ecut;
/**
 * 通过 自己的 Date 类理解 java.util.Date 类的内部设计
 */
public class MyDate {
	
	private transient long fastTime ; // 用来存储毫秒值
	
	public MyDate() {
		this( System.currentTimeMillis() ); // 调用另外一个构造方法
	}

	public MyDate( long date ) {
		super();
		fastTime = date ;
	}
	
	public void setTime(long time) {
        fastTime = time;
    }
	
	public long getTime() {
        return this.fastTime ;
    }

}
DateTest1.java
package cn.edu.ecut;

import java.util.Date;

/**
 * 1、类 Date 表示特定的 瞬间 ,精确到毫秒 
 * ( The class Date represents a specific instant in time, with millisecond precision . )
 * 2、Date 类的实例内部封装了一个 毫秒值 ( 从 历元 至 某一瞬间 所经历的 毫秒值 )
 * 3、历元( Epoch ) : 1970 年 1 月 1 日 00:00:00 GMT ( GMT : 格林尼治标准时间 )
 * 4、CST : China Standard Time , 中国标准时间
 */
public class DateTest1 {

	public static void main(String[] args) {
		
		// 使用 Date 类的 无参构造 创建 Date 实例
		Date now = new Date(); 
		System.out.println( now );
		
		long millis = System.currentTimeMillis() ; // 获取 从 历元 至 现在所经历的 毫秒数 ( 毫秒值 )
		System.out.println( millis );
		// 使用 Date 类带有一个 long 类型参数的构造 创建 Date 实例
		Date date = new Date( millis ); 
		System.out.println( date ); // 相当于date.toString()
		
		long ms = date.getTime(); // 获取在 Date 实例内部封装的 毫秒值
		System.out.println( ms );
		
		date.setTime( 1000000L ); // 以ms为单位
		System.out.println( date );
		
		long t = date.getTime(); // 获取在 Date 实例内部封装的 毫秒值
		System.out.println( t );
		
	}

}

2、比较Date实例:equals/before/after方法

DateTest2.java
package cn.edu.ecut;

import java.util.Date;

/**
 * 1、1h = 60m ; 1m = 60s ; 1s = 1000 ms ;
 * 2、比较两个 Date 实例是否相等: public boolean equals( Object o )
 * 3、判断 当前Date实例 所表示瞬间 是否 早于 另一个Date实例所表示的瞬间: boolean before( Date when )
 * 4、判断 当前Date实例 所表示瞬间 是否 晚于 另一个Date实例所表示的瞬间: boolean after( Date when )
 * 5、了解一下 "闰秒" : 对于 UTC,大约每一两年出现一次额外的一秒,称为 "闰秒"
 */
public class DateTest2 {

	public static void main(String[] args) {
		
		long millis = System.currentTimeMillis(); // 该行代码执行时对应的毫秒值
		Date now = new Date( millis );
		System.out.println( now );
		
		long day = 1000L * 60 * 60 *24 ; // 统计 24 小时对应的毫秒值,1000L为1000ms
		
		Date first = new Date(  millis - day );
		System.out.println( first );
		
		Date second = new Date(  millis  );
		System.out.println( second );
		
		Date third = new Date(  millis + day  );
		System.out.println( third );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
        //java.util.Calendar类重写了equals()方法
		System.out.println( first.equals( now ) ); // false
		System.out.println( second.equals( now ) ); // true
		System.out.println( third.equals( now ) ); // false
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		System.out.println( first.before( now ) ); // true
		System.out.println( second.before( now ) ); // false
		System.out.println( third.before( now ) ); // false
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		System.out.println( first.after( now ) ); // false
		System.out.println( second.after( now ) ); // false
		System.out.println( third.after( now ) ); // true	
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		// 以下比较方法就不赞成使用了
		System.out.println( first.getTime() <  now.getTime() ); 
		System.out.println( second.getTime() <  now.getTime() ); 
		System.out.println( third.getTime() < now.getTime() ); 
		
	}

}

3、理解java.util.Calendar类的设计和作用

CalendarTest1.java
package cn.edu.ecut;

import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * 1、java.util.Calendar 类是个抽象类
 * 2、java.util.GregorianCalendar 类是 Calendar 的子类
 * 3、Calendar 为特定瞬间与一组日历字段之间的转换提供了一些方法,并为操作日历字段提供了一些方法
 *       日历字段 ( calendar field ) 就是表示 特定瞬间 中某个部分的 字段 ,比如:
 *       Calendar.YEAR 表示年 、
 *       Calendar.MONTH 表示月、
 *       Calendar.DATE 表示天 、
 *       Calendar.HOUR 表示小时 ( 12 小时进制 ,分上午和下午 ) 、
 *       Calendar.HOUR_OF_DAY 表示小时 ( 24 小时进制 ) 、
 *       Calendar.MINUTE 表示分钟 、
 *       Calendar.SECOND 表示秒 、
 *       Calendar.MILLISECOND 表示毫秒
 * 4、瞬间 可用毫秒值来表示,它是距历元的偏移量
 * 		 历元:  即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历
 * 5、通过 Calendar 实例 调用 get( int) 方法可以获得指定 日历字段 的值
 */
public class CalendarTest1 {
	
	public static void main(String[] args) {
		
		// 父类类型的 引用变量 指向了 子类类型的对象
		Calendar calendar = new GregorianCalendar(); // 默认地区 、默认时区
		System.out.println( calendar );
		
		StringBuilder builder = new StringBuilder();
		
		int year = calendar.get( Calendar.YEAR );
		builder.append( year + "年" );
		
		// 鬼子那边的月份是从 零 开始计数的
		int month = calendar.get( Calendar.MONTH ) + 1 ; // ******
		builder.append( month + "月" );
		
		int date = calendar.get( Calendar.DATE );
		builder.append( date + "日" );
		
		int hours = calendar.get( Calendar.HOUR_OF_DAY );
		builder.append( hours + ":" );
		
		int minutes = calendar.get( Calendar.MINUTE );
		builder.append( minutes + ":" );
		
		int seconds = calendar.get( Calendar.SECOND );
		builder.append( seconds + "." );
		
		int millis = calendar.get( Calendar.MILLISECOND );
		builder.append( millis );
		
		String s = builder.toString();
		System.out.println( s );
	}
	
}

4、通过set方法设置Calendar类的实例所表示的瞬间

CalendarTest2.java
package cn.edu.ecut;

import java.util.Calendar;

/**
 * 1、通过 静态工厂方法 来获取 Calendar 类的实例
 * 		  ( 这里的 静态工厂方法 就是 Calendar 类中的 返回 Calendar实例 的 类方法getInstance )
 * 2、设置 Calendar 实例所表示的 瞬间 :
 * 			public void set( int field , int value ) 为 指定的日历字段 设置 指定的值,比如 c.set( Calendar.YEAR , 1999 )
 * 			public final void set( int year , int month , int date )
 * 			public final void set( int year , int month , int date , int hourOfDay , int minute )
 * 		    public final void set( int year , int month , int date , int hourOfDay , int minute , int second )
 */
public class CalendarTest2 {
	
	public static void main(String[] args) {
		
		String s ;
		
		// 父类类型的 引用变量 指向了 子类类型的对象
        // Calender calender = new GregorianCalendar();
		Calendar calendar = Calendar.getInstance(); // 默认地区 、 默认时区
		System.out.println( calendar );
		System.out.println( calendar.getClass() ); // 运行时类型
		 // 在 同一个类中使用 本类声明的 类方法时可以省略类名
		s = toString( calendar ) ; // s = CalendarTest2.toString( calendar ) ;
		System.out.println( s );
		
		/*
		calendar.set( Calendar.YEAR ,  1999 );
		calendar.set( Calendar.MONTH , 5 ); // 注意: 鬼子那边月份从零开始计数
		calendar.set( Calendar.DATE , 10 );
		calendar.set( Calendar.HOUR_OF_DAY , 7 );
		calendar.set( Calendar.MINUTE , 50 );
		calendar.set( Calendar.SECOND , 0);
		calendar.set( Calendar.MILLISECOND , 0 );
		*/
		
		calendar.set( 1999 , 5 , 10, 7, 50 , 0 );
		calendar.set( Calendar.MILLISECOND , 0 );
		
		System.out.println( calendar );
		
		s = toString( calendar ) ; 
		System.out.println( s );
		
	}
	
	public static String toString( Calendar calendar ) {
		StringBuilder builder = new StringBuilder();
		
		int year = calendar.get( Calendar.YEAR );
		builder.append( year + "年" );
		
		// 鬼子那边的月份是从 零 开始计数的
		int month = calendar.get( Calendar.MONTH ) + 1 ;
		builder.append( month + "月" );
		
		int date = calendar.get( Calendar.DATE );
		builder.append( date + "日" );
		
		int hours = calendar.get( Calendar.HOUR_OF_DAY );
		if( hours < 10 ) {
			builder.append( '0' );
		}
		builder.append( hours + ":" );
		
		int minutes = calendar.get( Calendar.MINUTE );
		if( minutes < 10 ) {
			builder.append( '0' );//补零
		}
		builder.append( minutes + ":" );
		
		int seconds = calendar.get( Calendar.SECOND );
		if( seconds < 10 ) {
			builder.append( '0' );
		}
		builder.append( seconds + "." );
		
		int millis = calendar.get( Calendar.MILLISECOND );
		builder.append( millis );
		
		String s = builder.toString();
		return s ;
	}
	
}

5、通过java.util.Calendar类的实例来获取java.util.Date实例

CalendarTest3.java
package cn.edu.ecut;

import java.util.Calendar;
import java.util.Date;

/**
 * 1、如果不是使用 JDK 1.8 提供的 日期/时间 支持 ( 不是使用 java.time 包 提供的支持 ),
 *      但需要获得 指定 年、月、日、时、分、秒 、毫秒 对应的 java.util.Date 实例 ,
 *      则可以借助于 Calendar 实例来实现
 * 2、通过 clear 方法可以 清空 Calendar 实例的所有 日历字段值 和 时间值
 */
public class CalendarTest3 {
	
	public static void main(String[] args) {
		
		// 1、获得一个 Calendar 实例
		final Calendar calendar = Calendar.getInstance(); // 默认地区、默认时区
		System.out.println( calendar );

		// 2、清空 Calendar 实例的所有 日历字段值 和 时间值
		calendar.clear(); // 将 当前Calendar实例 的所日历字段值和时间值(从历元至现在的毫秒偏移量)设置成未定义
		
		System.out.println( calendar );
		
		// 3、根据实际需要设置 年、月、日、时、分、秒 、毫秒
		calendar.set( 1999 , 9 , 10 , 16, 30, 40 ); // 注意月份从零开始计数
		calendar.set( Calendar.MILLISECOND , 123 );// 如有必要可以单独设置毫秒
		
		System.out.println( calendar );
		
		// 4、通过 Calendar 实例来获得 Date 对象
		Date date = calendar.getTime(); // 通过 Calendar实例 获得该实例所表示瞬间对应的 Date 对象
		System.out.println( date );
		
		long millis = calendar.getTimeInMillis(); // 通过 Calendar实例 获得该实例所表示瞬间 对应的毫秒值
		System.out.println( millis );
		
	}
	
}

6、理解国家/地区(Locale)和时区(TimeZone)对Calendar的影响

CalendarTest4.java
package cn.edu.ecut;

import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;

/**
 * 1、时区: TimeZone 、地区: Locale
 * 2、获得 Calendar 实例时需要综合考虑 地区 和 时区 的影响
 */
public class CalendarTest4 {
	
	public static void main(String[] args) {
		
		// 获得 默认的地区 ( 用一个 Locale 对象表示 )
		Locale defaultLocale = Locale.getDefault(); // 类方法
		System.out.println( defaultLocale );
		
		Locale first = new Locale( "zh" , "CN" ); //(“中文”,“地区”)
		System.out.println( first );
		
		Locale second = new Locale( "zh" , "TW" );
		System.out.println( second );
		
		Locale third = new Locale( "en" , "US" );
		System.out.println( third );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		// 获得 默认的时区 ( 用一个 TimeZone 对象表示 )
		TimeZone defaultTimeZone = TimeZone.getDefault() ; // 类方法
		System.out.println( defaultTimeZone );
		
		String id = "Asia/Chongqing" ;
		TimeZone tz = TimeZone.getTimeZone( id );
		System.out.println( tz );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		/*
		String[] ids = TimeZone.getAvailableIDs();
		for( int i = 0 ; i < ids.length ; i++ ) {
			System.out.println( ids[ i ] );
		}
		*/
		
		Calendar calendar = Calendar.getInstance( tz , first );
		System.out.println( calendar );
		
		System.out.println( calendar.getTime() );
		
	}
	
}

7、理解java.tim.LocalDate类的设计并获取其实例,通过该类实例测试其常用方法

LocalDateTest.java
package cn.edu.ecut;

import java.time.LocalDate;

/**
 * 1、了解 LocalDate 中的常量:  MIN / MAX / EPOCH
 * 2、熟练使用 LocalDate 类中的 静态工厂方法 :  now() / of( int , int , int ) / ofYearDay( int , int )
 * 3、理解 LocalDate 内部设计: 
 *          LocalDate 类是 final 修饰的 、
 *          LocalDate 类的构造方法都是私有的、
 *          LocalDate 类中表示 年、月、日的 实例变量全部都是 私有 且 不可更改的:
 *           private final int year ;
 *           private final short month ;
 *           private final short date ;
 *  4、LocalDate 类是一个最终类,同时 LocalDate 类的实例 也是不可变的
 */
public class LocalDateTest {

	public static void main(String[] args) {
		
		System.out.println( LocalDate.MIN ); 
		System.out.println( LocalDate.EPOCH ); // 历元
		System.out.println( LocalDate.MAX ); 
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		LocalDate today = LocalDate.now(); // 获得当前日期
		System.out.println( today );
		
		LocalDate birthdate1 = LocalDate.of( 1999 ,  5 , 10 ); // 注意这里的月份从一开始
		System.out.println( birthdate1 );
		
		LocalDate birthdate2 = LocalDate.of( 1999 ,  5 , 10 ); 
		System.out.println( birthdate2 );
		
		System.out.println( birthdate1 == birthdate2 ); // false
		System.out.println( birthdate1.equals( birthdate2 ) ); // true
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		System.out.println( today.plusDays( 15 ) ); // 增加 N 天
		System.out.println( today.plusWeeks( 3 ) ); // 增加 N 周
		System.out.println( today.plusMonths( -5 ) );
		System.out.println( today.plusYears( -10 ) );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		LocalDate date = LocalDate.ofYearDay( 2020 , 200 ); // 获取 指定年份 的 第 N 天对应的 日期
		System.out.println( date );
		System.out.println( date.isLeapYear() ); // 判断 指定日期 所在年份是否是闰年
		System.out.println( date.lengthOfMonth() ); // 获取 当前日期 所在月份的总天数
		System.out.println( date.lengthOfYear() ); // 获取 当前日期 所在年份的总天数

	}

}

8、通过DateFormat中的类方法获取DateFormat实例并使用format方法完成日期格式化操作

DateFormatTest1.java
package cn.edu.ecut;

import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 1、通过 DateFormat 提供的 静态工厂方法 可以获得 DateFormat 实例,但是通常不会这样用
 *		 DateFormat.getInstance()
 *		 DateFormat.getDateInstance()
 *		 DateFormat.getTimeInstance()
 * 2、通过 DateFormat 实例的 format 方法可以将一个 Date实例 格式化为 特定模式 的字符串
 */
public class DateFormatTest1 {

	public static void main(String[] args) {
		
		final Calendar c = Calendar.getInstance();
		c.clear();
		c.set( 1999 , 9, 30, 19, 30 , 50 );
		
		final Date d = c.getTime();
		System.out.println( d );
		
		DateFormat df = DateFormat.getInstance(); // 获取默认语言环境的默认格式化风格
		
		// 将 Date实例 所表示的瞬间 用 特定格式 的 字符串 来表示
		String s = df.format( d ) ; // 将 Date实例 格式化 为特定的字符串 形式
		System.out.println( s );
		
		df = DateFormat.getDateInstance(); // 仅处理日期
		System.out.println( df.format( d ) );
		
		df = DateFormat.getTimeInstance(); // 仅处理时间
		System.out.println( df.format( d ) );

	}

}

9、使用 特定模式pattern 来创建SimpleDateFormat实例并将Date实例格式化

DateFormatTest2.java
package cn.edu.ecut;

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

/**
 * 1、通过创建 SimpleDateFormat 类的实例来完成 日期格式化操作
 * 2、在创建 SimpleDateFormat 对象时,一定要注意 日期模式
 */
public class DateFormatTest2 {

	public static void main(String[] args) {
		
		final Calendar c = Calendar.getInstance();
		c.clear();
		c.set( 1999 , 9, 30, 19, 30 , 50 );
		
		final Date d = c.getTime();
		System.out.println( d );
		
		// Locale.setDefault( new Locale( "en" , "US") ); // 设置默认的国家/地区
		
		// final String pattern = "Gyyyy年MM月dd日 E HH:mm:ss.SSS" ;
		final String pattern = "Gyyyy年MM月dd日 EEEE HH:mm:ss.SSS" ;
		// 父类类型的引用 变量 指向了 子类类型的对象
		DateFormat df = new SimpleDateFormat( pattern );
		
		String s = df.format( d ); // 将 Date实例 格式化为 特定模式 的 字符串
		System.out.println( s );

	}

}

10、利用SimpleDateFormat实例解析符合特定模式的字符串并创建与之对应的Date实例

DateFormatTest3.java
package cn.edu.ecut;

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

/**
 * 通过 SimpleDateFormat实例 来完成 将符合 特定模式 的 字符串 解析为 Date实例
 */
public class DateFormatTest3 {

	public static void main(String[] args) throws ParseException {
		
		String source = "公元2044年10月30日 星期日 19:30:50.000" ;
		
		final String pattern = "Gyyyy年MM月dd日 EEEE HH:mm:ss.SSS" ;
		// 父类类型的引用 变量 指向了 子类类型的对象
		DateFormat df = new SimpleDateFormat( pattern );
		
		Date d = df.parse( source ); // 可能触发 ParseException 异常
		System.out.println( d );

	}

}

11、理解java.time.ZoneId类的作用

ZoneIdTest.java
package cn.edu.ecut;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.TextStyle;
import java.util.Locale;
import java.util.Set;

/**
 * 1、了解 java.time.ZoneId 表示 时区
 * 2、ZoneId.systemDefault() 获取当前操作系统使用的时区
 * 3、ZoneId.getAvailableZoneIds() 获得当前JVM所支持的所有的 时区编号
 * 4、ZoneId.of( String zoneId ) 根据 指定的 时区编号 获得相应的 ZoneId实例
 * 5、对于 LocalDate 来说,时区不同,所表示的 日期也可能不同
 */
public class ZoneIdTest {

	public static void main(String[] args) {
		
		// 使用 ZoneId 类中的 systemDefault 方法获取当前操作系统使用的时区
		ZoneId zid = ZoneId.systemDefault() ;
		System.out.println( zid ); // 可以在 操作系统中 修改时区进行测试
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		// 根据指定的 时区编号( zoneId ) 来获取 相应的 ZoneId实例
		ZoneId zone = ZoneId.of( "US/Alaska" );
		System.out.println( zone );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		LocalDate date = LocalDate.now( zone );// 根据指定时区获得该地区当前时间
		System.out.println( date );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		date = LocalDate.now();// 根据默认时获得该地区当前时间
		System.out.println( date );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		Locale defaultLocale = Locale.getDefault();
		
		// 获得当前JVM所支持的所有 时区编号( zoneId )
		Set<String>  set = ZoneId.getAvailableZoneIds();		
		Object[] array = set.toArray(); // 将 Set 集合转换为 数组
		for( int i = 0 , n = array.length ; i < n ; i ++ ) {
			String id = (String)array[ i ] ;
			ZoneId zoneId = ZoneId.of( id );
			System.out.println( id + " : " + zoneId.getDisplayName( TextStyle.FULL , defaultLocale ) );
		}
        
        /*
        Set<String>  set = ZoneId.getAvailableZoneIds();		
		Object[] array = set.toArray(); 
		for( int i = 0 , n = array.length ; i < n ; i ++ ) {
			System.out.println( array[i] );
		}
        */

	}

}

12、理解java.time.LocalTime类的设计并获取其实例,通过该类的实例测试其常用方法

LocalTimeTest.java
package cn.edu.ecut;

import java.time.LocalTime;
import java.time.ZoneId;

/**
 * 1、理解 java.time.LocalTime 表示某一天当中的时间
 * 2、通过 LocalTime 类的 类方法 来获取 LocalTime 实例: now() / now(ZoneId) / of( int , int ) / of( int , int , int ) / of ( int , int , int , int)
 * 3、秒( s ) 、毫秒 ( ms )、微秒(μs)、纳秒(ns) 、皮秒(ps)之间的换算
 *      1s = 1000ms 。[ 毫秒 ( millisecond ) ]
 *      1ms = 1000μs 。[ 微秒 ( microsecond ) ]
 *      1μs = 1000ns 。[ 纳秒 也叫 毫微秒 ( nanosecond ) ]
 *      1ns = 1000ps 。[ 皮秒 ( picosecond ) ]
 */
public class LocalTimeTest {

	public static void main(String[] args) {
		
		System.out.println( ZoneId.systemDefault() ); // 输出操作系统使用的默认时区
		
		 LocalTime now = LocalTime.now(); // 根据默认时区获取当地的当前时间
		 System.out.println( now );
		 
		 ZoneId zone = ZoneId.of( "US/Alaska" );
		 now = LocalTime.now( zone ); // 根据 指定时区 获取该地当前时间
		 System.out.println( now );
		 
		 System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		 
		 LocalTime first = LocalTime.of( 15 ,  35 );
		 System.out.println( first ); // 输出15:53
		 
		 LocalTime second = LocalTime.of( 15 ,  35 , 40 );
		 System.out.println( second ); // 输出15:53:40
		 
		 LocalTime third = LocalTime.of( 22 , 44 ,  55 , 100200300 ); // 时、分、秒、纳秒
		 System.out.println( third ); // 输出22:44:55.100200300
		 
		 System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		 
		 System.out.println( LocalTime.MIN );
		 System.out.println( LocalTime.MAX );
		 System.out.println( LocalTime.MIDNIGHT );
		 System.out.println( LocalTime.NOON );
		 
	}

}

13、理解LocalDateTime类的作用/获取LocalDateTime实例

LocalDateTimeTest.java
package cn.edu.ecut;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;

/**
 * 1、了解 java.time.LocalDateTime 表示 日期时间,其中既有日期又有时间 
 * 2、LocalDateTime类中的类方法: now() / now(ZoneId) / of( ... )
 *
 */
public class LocalDateTimeTest {

	public static void main(String[] args) {

		System.out.println(LocalDateTime.MIN);
		System.out.println(LocalDateTime.MAX);

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

		LocalDateTime now = null;

		// 使用操作系统使用 默认时区 获得 LocalDateTime 实例
		now = LocalDateTime.now();
		System.out.println(now); // now.toString() 
        
        /*
        LocalDateTime now = LocalDateTime.now();// 输出系统默认时区的当前时间
        // 2020-0602T15:33:14.326133,此处的T是Java8中新支持的写法
        */

		// 根据 指定时区(ZoneId.of("US/Alaska")) 获取该时区对应的 日期时间
        /*
        ZoneId zone = ZoneId.of("US/Alaska");
        now=LocalDateTime.now(zone);
        */
		now = LocalDateTime.now(ZoneId.of("US/Alaska"));
		System.out.println(now);

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

		LocalDate date = LocalDate.of(1998, 6, 10);
		LocalTime time = LocalTime.of(14, 20, 30, 111222333);

		LocalDateTime first = LocalDateTime.of(date, time);
		System.out.println(first);

		LocalDateTime second = LocalDateTime.of(1999, 7, 8, 5, 30);
		System.out.println(second);

		LocalDateTime third = LocalDateTime.of(1999, 7, 8, 5, 30, 40);
		System.out.println(third);

	}

}

14、将LocalDateTime转换为LocalDate或LocalTime

TransformTest1.java
package cn.edu.ecut;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * 1、LocalDateTime ===>  LocalDate(toLocalDate())
 * 2、LocalDateTime ===>  LocalTime(toLocalTime())
 */
public class TransformTest1 {

	public static void main(String[] args) {
		
		LocalDateTime now = LocalDateTime.now(); // 默认时区(系统默认时区的当前时间)
		System.out.println( now ); // 输出日期与时间
		
		// LocalDateTime ===>  LocalDate
		LocalDate date = now.toLocalDate();
		System.out.println( date ); // 输出日期
		
		// LocalDateTime ===>  LocalTime
		LocalTime time = now.toLocalTime();
		System.out.println( time ); // 输出时间

	}

}

15、将LocalDate实例转换为LocalDateTime实例

TransformTest2.java
package cn.edu.ecut;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 *  LocalDate ===>  LocalDateTime
 *	atStartOfDay()
 *	atTime( hour , minute )
 *	atTime( hour , minute , second)
 *	atTime( hour , minute , second , nanosecond)
 *	date.atTime( time )
 */
public class TransformTest2 {

	public static void main(String[] args) {
		
		LocalDate date = LocalDate.ofYearDay( 1999 ,  200 );
		System.out.println( date );
		
		// 获得 date 所表示日期的 00:00:00.000000000 对应的 LocalDateTime实例
		LocalDateTime first = date.atStartOfDay(); 
        //日期以date所表示的日期为准,时间以这天的开始时间为准
		System.out.println( first ); // 1999-7-19T00:00
		
		LocalDateTime second = date.atTime( 5 , 30 );
		System.out.println( second );// 1999-7-19T05:30
		
		LocalDateTime thrid = date.atTime( 5 , 30 , 40 );
		System.out.println( thrid );
		
		LocalDateTime fourth = date.atTime( 5 , 30 , 40 , 100200300 );
		System.out.println( fourth );
		
		LocalTime time = LocalTime.of( 17 ,  20 , 30, 400500600 );
		LocalDateTime fifth = date.atTime( time );
		System.out.println( fifth );

	}

}

16、将LocalTime实例转换为LocalDateTime实例

TransformTest3.java
package cn.edu.ecut;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * LocalTime ===>  LocalDateTime
 *	time.atDate( date )
 */
public class TransformTest3 {

	public static void main(String[] args) {
		
		LocalTime time = LocalTime.of( 16 ,  50 , 30, 400500600 );
		System.out.println( time );
		
		LocalDate date = LocalDate.now(); // 默认时区
		
		LocalDateTime first = time.atDate( date );
		System.out.println( first );

	}

}

17、将java.util.Date实例转换为LocalDateTime/LocalDate/LocalTime类型

TransformTest4.java
package cn.edu.ecut;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;

/**
 * 1、java.util.Date ===>  java.time.LocalDateTime
 * 			java.util.Date ---> java.time.Instant ---> java.time.ZonedDateTime ---> java.time.LocalDateTime
 * 2、java.util.Date ===>  java.time.LocalDate
 * 			java.util.Date ---> java.time.Instant ---> java.time.ZonedDateTime ---> java.time.LocalDate
 * 3、java.util.Date ===>  java.time.LocalTime
 * 			java.util.Date ---> java.time.Instant ---> java.time.ZonedDateTime ---> java.time.LocalTime
 */
public class TransformTest4 {

	public static void main(String[] args) {
		
		Calendar c = Calendar.getInstance();
		c.clear();
		c.set( 1999 ,  9 ,  10 ,  20 ,  30 ,  40 );
		final Date utilDate = c.getTime();
		System.out.println( utilDate );
		
		// 根据 java.util.Date 实例 获得 与之对应的 java.time.Instant 实例
		Instant instant = utilDate.toInstant(); 
		System.out.println( instant );
		
		ZoneId zone = ZoneId.systemDefault();
		// 根据 Instant 实例获得 带有时区的 日期时间对象 ( ZonedDateTime实例 )
		ZonedDateTime zdt = instant.atZone( zone );
		System.out.println( zdt );
		
		// ZonedDateTime ===> LocalDateTime
		LocalDateTime datetime = zdt.toLocalDateTime() ;
		System.out.println( datetime );
		
		// ZonedDateTime ===> LocalDate
		LocalDate date = zdt.toLocalDate() ;
		System.out.println( date );
		
		// ZonedDateTime ===> LocalTime
		LocalTime time = zdt.toLocalTime() ;
		System.out.println( time );

	}

}

18、将LocalDateTime/LocalDate/LocalTime类型的实例转换为java.util.Date实例

TransformTest5.java
package cn.edu.ecut;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;

/**
 * 1、java.time.LocalDateTime ===> java.util.Date
 * 			java.time.LocalDateTime ---> java.time.ZonedDateTime ---> java.time.Instant ---> java.util.Date
 * 2、java.time.LocalDateTime ===> java.time.ZonedDateTime
 * 3、java.time.ZonedDateTime ===> java.time.Instant
 * 4、java.time.Instant ===> java.util.Date
 */
public class TransformTest5 {

	public static void main(String[] args) {
		
		LocalDate date = LocalDate.of( 1949 , 10 , 1 );
		LocalTime time = LocalTime.of( 10 , 0 );
		LocalDateTime datetime = LocalDateTime.of( date , time );
		System.out.println( datetime );
		
		ZoneId zone = ZoneId.systemDefault() ;
		
		// ZonedDateTime zonedDateTime = ZonedDateTime.of( date , time , zone );
		ZonedDateTime zonedDateTime = ZonedDateTime.of( datetime , zone );
		
		// ZonedDateTime 类 实现了 TemporalAccessor 接口
		Instant instant = Instant.from( zonedDateTime ) ;
		
		// 将一个 java.time.Instant 实例 转换为 java.util.Date 实例
		Date utilDate = Date.from( instant ) ;
		System.out.println( utilDate );
        
        // java.util.Date类的类方法:public static Date from(Instant instant)
		
	}

}

19、了解java.sql包中的Date和Time类并测试其valueOf方法、toLocalDate/toLocalTime方法

TransformTest6.java
package cn.edu.ecut;

import java.time.LocalTime;

/**
 * 1、java.sql.Date 类 和 java.sql.Time 类 都是 java.util.Date 类的子类
 * 2、使用 java.util.Date 类型的引用变量 可以 指向 java.sql.Date 类型的实例 或  指向java.sql.Time 类型的实例
 * 3、因此:
 *      将 java.time.LocalDate 快速转换为 java.util.Date 的方法就是 java.sql.Date.valueOf( java.time.LocalDate ) ,
 *      将 java.time.LocalTime 快速转换为 java.util.Time 的方法就是 java.sql.Time.valueOf( java.time.LocalTime ) ,
 * 		 但是他们的确是不完美的。
 */
public class TransformTest6 {

	public static void main(String[] args) {
		
		long millis = 1000L * 60 * 60 * 24 * 365 * 50 ;
		// java.sql.Date 类 是 java.util.Date 类的子类,用来表示日期
		java.sql.Date date = new java.sql.Date( millis );
		System.out.println( date ); 
		
		// 直接将 java.sql.Date 实例转换为 java.time.LocalDate 实例
		java.time.LocalDate localDate = date.toLocalDate(); 
		System.out.println( localDate );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		long ms = 1000L * 60 * 60 * 15 ;
		// java.sql.Time 类 是 java.util.Date 类的子类,用来表示时间
		java.sql.Time time = new java.sql.Time( ms );
		System.out.println( time );
		
		LocalTime localTime = time.toLocalTime();
		System.out.println( localTime );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		java.time.LocalDate birthdate = java.time.LocalDate.of( 1998 , 10 , 20 );
		System.out.println( birthdate );
		// 使用 java.sql.Date 类中的 valueOf 方法将 LocalDate 转换为 java.sql.Date 实例
		java.sql.Date sqlDate = java.sql.Date.valueOf( birthdate );
		System.out.println( sqlDate );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		java.time.LocalTime now = java.time.LocalTime.now();
		java.sql.Time sqlTime = java.sql.Time.valueOf( now );
		System.out.println( sqlTime );
		
	}

}

20、通过为Person类定义birthdate字段来理解LocalDate的使用

Person.java
package cn.edu.ecut;

import java.time.LocalDate;

public class Person {

	private String name;
	private char gender;
	// 在不跟项目经理干架的前提下,建议使用 java.time.LocalDate 而不是使用 java.util.Date
	private LocalDate birthdate; // private Date birthdate ;
	private boolean married;

	public Person() {
		super();
	}

	public Person(String name, char gender, LocalDate birthdate, boolean married) {
		super();
		this.name = name;
		this.gender = gender;
		this.birthdate = birthdate;
		this.married = married;
	}
	

	@Override
	public String toString() {
		return "{ name : " + name + " , gender : " + gender +
					" , birthdate : " + ( birthdate == null ? "" : birthdate.toString() ) + " , married : " + married + " }";
	}
	
	public boolean marry( Person another ) {
		// 如何根据日期来获取一个人的年龄
		LocalDate today = LocalDate.now();
		int y1 = today.getYear(); // 获得年份
		int y2 = birthdate.getYear(); // 获得年份
		System.out.println( y1 - y2 ); // 当前Person对象的年龄
		
		// 其它代码省略
		
		return false ;
	}

	public String getName() {
		return name;
	}
	

	public char getGender() {
		return gender;
	}
	

	public LocalDate getBirthdate() {
		return birthdate;
	}
	

	public boolean isMarried() {
		return married;
	}
	

	public void setName(String name) {
		this.name = name;
	}
	

	public void setGender(char gender) {
		this.gender = gender;
	}
	

	public void setBirthdate(LocalDate birthdate) {
		this.birthdate = birthdate;
	}
	

	public void setMarried(boolean married) {
		this.married = married;
	}

}
PersonTest.java
package cn.edu.ecut;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;

public class PersonTest {

	public static void main(String[] args) {
		
		LocalDate firstDate = LocalDate.of( 1999 , 10 , 20 );
		Person first = new Person( "杨过" , '男' , firstDate , false );
		System.out.println( first );
		
		LocalDate secondDate = LocalDate.of( 2014 , 5 , 8 );
		Person second = new Person( "郭襄" , '女' , secondDate , false );
		System.out.println( second );
		
		second.marry( first );
		
		System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
		
		LocalDateTime now = LocalDateTime.now() ;
		LocalDateTime dt = LocalDateTime.of( 1999, 1, 1, 15, 0);
		
		Duration d = Duration.between( dt ,  now );
		
		System.out.println( d.toDays() );

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值