重新开始学Java——时间与日期

本篇博客会详细叙述时间与日期的相关的类与方法,包括jdk1.8之后新出的类和方法等。首先来介绍的是JDK1.8之前就已经出的关于时间的类。

java.util.Date

在官方API中进行的描述如下:

The class Date represents a specific instant in time, with millisecond precision.(类 date 表示特定的时间瞬间, 具有毫秒精度。)

那么在这里也就是说这里会产生一个具体的日期,表示一个特定的瞬间,可以表示到毫秒精度,首先来看构造方法(已经被标记过时的构造方法不看):

	Date():Allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond.(分配 date 对象并对其初始化, 使其表示分配该对象的时间, 测量到最接近的毫秒。)
	
	Date( long date ) : Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.(分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。)

通过构造可以看到,有两个没有过时的构造方法,那么就可以通过构造来构造指定的对象。示例如下:

public class TestDate1 {
    public static void main(String[] args) {
        // 利用无参构造来进行创建对象
        Date date = new Date() ;
        // 此时输出的是 date 对象的字符串形式( 那么也就是表示调用的是toString方法 )
        System.out.println( date ); // Sat Nov 24 14:30:04 CST 2018
        /**
         * System.currentTimeMillis() 表示 返回当前时间距离到历元之间的毫秒值
         */
        long ms = System.currentTimeMillis() ;
        /**
         * 使用带有参数的构造
         * 注意 : 这个参数表示从 1900年1月1日 00:00:00 之后的毫秒值
         */
        date = new Date( ms ) ;
        System.out.println( date ); // Sat Nov 24 14:30:04 CST 2018

        /**
         * 利用指定的毫秒值 加上一个小时的毫秒值, 作为参数,传入到Date的构造中
         */
        ms = System.currentTimeMillis() + 1000 * 60 * 60 ;
        date = new Date( ms ) ;
        System.out.println( date ); // Sat Nov 24 15:30:04 CST 2018
    }
}

那么在这里就可以看到如何去创建一个java.util.Date对象,接下来可以看一下具体的方法(没有标记成过时的方法):

  • getTime() & setTime()

这是一对方法,分别表示获取时间,设置时间;具体描述如下:

	getTime() : Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.(返回此 date 对象表示的自 1970年1月1日 00 gmt 以来的毫秒数。)
	setTime(long time ):Sets this Date object to represent a point in time that is time milliseconds after January 1, 1970 00:00:00 GMT.(将此 date 对象设置为表示 1970年1月1日 00:00 gmt 之后的时间点。)

通过官方API的描述就可以发现,getTime方法主要是获取到的是从历元之后的毫秒值;而setTime( long time ) 主要是将毫秒值设置到指定的Date对象中。示例如下:

public class TestDate2 {
    public static void main(String[] args) {
        /**
         * 输出从历元至今经历的毫秒值
         */
        System.out.println( System.currentTimeMillis() ); // 1543041845579
        // 创建java.util.Date 对象
        Date date = new Date() ;
        // 获取到Date对象从历元至今的毫秒值
        long ms = date.getTime() ;
        /**
         * 可以发现是相同的,那么也就是说getTime与 System.currentTimeMillis() 返回的值是一样的
         */
        System.out.println(  ms  ); // 1543041845579
        /**
         * 设置的值只有1000 毫秒,那么date所表示的时间就会被改变
         */
        date.setTime( 1000 );
        System.out.println( date ); // Thu Jan 01 08:00:01 CST 1970
    }
}

注意:如果想要看到date对象中的日期进行了更改,可以同时输出两次进行比较。

  • after & befor & equals

这里是一组方法,因为这三个方法都是针对于时间进行比较的,依旧是先来看方法描述:

	after​(Date when):Tests if this date is after the specified date.( 测试此日期是否在指定日期之后。 )
	befor( Date when):Tests if this date is before the specified date.(测试此日期是否在指定日期之前。)
	equals( Object obj ) : Compares two dates for equality.(比较两个日期是否相等。)

可以看到这三个方法都是用于时间进行比较的方法,但是要注意,equals方法其本质用来比较两个对象是否相等,但是在这里的描述是比较两个日期对象,所以要注意一下。示例如下:

public class TestDate3 {
    public static void main(String[] args) {
        long ms = System.currentTimeMillis() ;
        Date date = new Date(  ms ) ;
        System.out.println( date ); //Sat Nov 24 15:05:47 CST 2018
        /**
         * 在这里表示比指定的时间多了 1ms
         */
        Date date2 = new Date( ms + 1 ) ;
        System.out.println( date2 ); // Sat Nov 24 15:05:47 CST 2018
        // 判断 date 是否在 date2 之后 ,返回boolean 类型的值
        System.out.println( date.after( date2 ) ); // false
        // 判断date 是否在date2 之前 , 返回boolean 类型的值
        System.out.println( date.before( date2 )); // true
        // 判断date 与 date2 是否相等
        System.out.println( date.equals( date2 )); // false 
    }
}

那么此时要注意的是equals方法,这个方法是重写来自于父类java.lang.Object类,可以参看源码:

public boolean equals(Object obj) {
		// 使用instanceof 进行类型判断,在通过getTime进行比较毫秒值
        return obj instanceof Date && getTime() == ((Date) obj).getTime();
    }

这个源码是比较简单的,但是如果想要查看after与before方法的源码的话,要做好心里准备。

  • compareTo

这个方法的名字已经很熟悉了,但是依旧是要查看一下。官方API描述如下:

compareTo​(Date anotherDate) : Compares two Dates for ordering.(比较两个日期的顺序)

那么在这里要明确一下,是比较顺序,那么这个顺序就是自然排序,那么这个方法的返回值如下:

the value 0 if the argument Date is equal to this Date; a value less than 0 if this Date is before the Date argument; and a value greater than 0 if this Date is after the Date argument.(如果参数日期等于此日期,则值0;如果此日期在Date参数之前,则值小于0;如果此日期是Date参数之后,则值大于0。)

注意:如果参数日期等于这个调用的日期,那么就返回0;如果调用的日期对象在参数日期之前,那么就返回小于0 的值;如果调用的日期对象在参数日期之后,那么就返回大于0的值。具体示例如下:

public class TestDate4 {
    public static void main(String[] args) {
        Date date = new Date() ;
        Date date2 = new Date( 2 ) ;
        System.out.println( date.compareTo( date2 ));
    }
}

使用起来比较简单,但是要清楚如何比较的,源码如下:

 public int compareTo(Date anotherDate) {
 		// 获取到对应的毫秒值
        long thisTime = getMillisOf(this);
        long anotherTime = getMillisOf(anotherDate);
		// 进行返回操作(三目运算符)
        return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
    }
// getMillisOf( Date date )
static final long getMillisOf(Date date) {
        if (date.getClass() != Date.class) { // 如果两个类型不相同的话,直接返回对应的毫秒之
            return date.getTime();
        }
        if (date.cdate == null || date.cdate.isNormalized()) {
            return date.fastTime;//这里也是返回对应的毫秒值
        }
        BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone(); // 复制一个对象
        return gcal.getTime(d); // 获取对应的毫秒值 
    }
  • hashcode

这个方法来自于父类java.lang.Object,但是进行了重写。具体示例这里就不描述了,主要看源码:

public int hashCode() {
        long ht = this.getTime();
        return (int) ht ^ (int) (ht >> 32);
    }

通过源码可以发现是通过获取对应的毫秒值进行操作,如果两个Date对象有相同的毫秒值,则认为是相等的(当调用equals方法应该是返回true)。而在Java.lang.Object中是针对于对象进行操作的。

  • toInstant()

该方法是JDK1.8之后出的方法,主要返回一个Instant对象,具体描述如下:

Converts this Date object to an Instant.The conversion creates an Instant that represents the same point on the time-line as this Date.(将此日期对象转换为Instant对象。转换将创建一个表示时间线上与此日期相同的点的Instant。)

注意,这个Instant对象会在后续的描述中进行书写,这里仅仅提一下。

java.util.Calendar

java.util.Calendar这个类主要是针对于java.util.Date类的一个补充,也就是说,因为java.util.Date类中有大量的过时方法,所以才会有这个类的出现。

java.util.Calendar是一个抽象类,具体描述如下:

public abstract class Calendar
extends Object
implements Serializable, Cloneable, Comparable<Calendar>

可以发现这个类是一个抽象类,那么也就是说这个类是没有办法通过 new Calendar() 这种方式构建对象。直接继承java.lang.Object,那么也就是说可能会重写来自父类的方法。实现Serializable, Cloneable, Comparable<Calendar>这三个接口,也就说这个类可以被复制,可以进行比较。

那么针对于这个类的作用,那么也可以参看官方API,那么这里仅仅查看一小段。如下所示:

The Calendar class is an abstract class that provides methods for converting between a specific instant in time and a set of calendar fields such as YEAR, MONTH, DAY_OF_MONTH, HOUR, and so on, and for manipulating the calendar fields, such as getting the date of the next week. An instant in time can be represented by a millisecond value that is an offset from the Epoch, January 1, 1970 00:00:00.000 GMT (Gregorian).[Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。]

那么在这里也就是说,Calendar是针对于java.util.Date的一个补充,其中包括了年月日等字段之间的转换。

  • Calendar的实例

其实每一个类中都是有构造的,那么针对于抽象类也是有构造方法的,但是不能自己调用构造方法来进行创建对象。所以在这里有构造是为什么呢?其实是为了让子类能够调用,具体的操作会放在类加载那里进行描述。接下来来看一下构造方法:

	protected Calendar():Constructs a Calendar with the default time zone and the default FORMAT locale.
	protected Calendar​(TimeZone zone, Locale aLocale):Constructs a calendar with the specified time zone and locale.

可以发现这个构造是protected进行修饰的,那么在这里表示构造方法不是供使用者调用的,而是供子类调用的。那么就需要清楚,如何获取Calendar的实例。可以通过java.util.Calendar中的静态方法来获取。如下所示:

	static Calendar	getInstance():Gets a calendar using the default time zone and locale.
	static Calendar	getInstance​(Locale aLocale):Gets a calendar using the default time zone and specified locale.
	static Calendar	getInstance​(TimeZone zone):Gets a calendar using the specified time zone and default locale.
	static Calendar	getInstance​(TimeZone zone, Locale aLocale):Gets a calendar with the specified time zone and locale.

这里描z.述了四个方法,都是获取Calendar实例的方法,可以不传入参数,也可以传入TimeZone对象,也可以传入Locale对象,同时两个都可以传入。那么在这里使用最简单的方法来获取Calendar对象,示例如下:

public class TestCalendar {
    public static void main(String[] args) {
        /**
         * 使用没有参数的静态方法,获取Calendar对象
         */
        Calendar c = Calendar.getInstance() ;
        /**
         * 可以查看到 GregorianCalendar 这个对象显示出来了
         * 因为 GregorianCalendar 类是 Calendar 的子类 
         */
        System.out.println( c ); // java.util.GregorianCalendar.....
    }
}

这里需要明确的是,输出的对象是Calendar的子类,是可以使用的。

  • Calendar中的常量

Calendar中有大量的字段分别对时间进行了描述,比如说:YEAR、MONTH、DATE、 DAY_OF_MONTH等,具体示例如下:

public class TestCalendar {
       public static void main(String[] args) {
              System.out.println( Calendar.YEAR ); // 年
              System.out.println( Calendar.MONTH ); // 月
              System.out.println( Calendar.DATE ); // 日期( 也就是说几号 )
              System.out.println( Calendar.DAY_OF_MONTH ); // 与上边的DATE 的效果是一样的
              System.out.println( Calendar.HOUR ) ; // 表示12小时
              System.out.println( Calendar.HOUR_OF_DAY ) ; // 表示二十四小时制
              System.out.println( Calendar.MINUTE ); // 分钟
              System.out.println( Calendar.SECOND ); // 秒
              System.out.println( Calendar.MILLISECOND ) ; // 毫秒
       }
}

注意,此时输出的数值表示具体的常量的含义,也就是说这些常量也就是表示一个简单的值,在API中有具体的描述,但是,这个Calendar的常量根本就不是这样使用的,具体的使用方式如下所示 :

/**
 * 在使用具体的 Calendar中的常量的时候,具体的get方法也就顺带说明
 */
public class TestCalendar2 {
       public static void main(String[] args) {
              // 创建一个Calendar类型的对象
              Calendar c = Calendar.getInstance() ;
              // 通过常量获取Calendar对象中各个"日历字段"的值
              System.out.println( c.get( Calendar.YEAR ) ) ; // 2018
              /**
               * get​(int field) :Returns the value of the given calendar field.
               * 表示获取给定的Calendar字段的值
               */
              System.out.println( c.get( Calendar.MONTH ) ) ; // 10,注意这个月份,此时表示的是11月份,也就是说输出的值总是比当前月份少1
              System.out.println( c.get( Calendar.DATE ) ) ; // 29
              System.out.println( c.get( Calendar.HOUR ) ) ; // 10
              System.out.println( c.get( Calendar.HOUR_OF_DAY ) ) ; // 10
              System.out.println( c.get( Calendar.MINUTE )); //45
              System.out.println( c.get( Calendar.SECOND ) ); // 7
              System.out.println( c.get( Calendar.MILLISECOND ) ); // 339
       }
}

如果有get方法,那么应该有对应的set方法,下面描述的就是对应的set方法。示例如下:

/**
 * 在使用具体的 Calendar中的常量的时候,具体的set方法也就顺带说明
 */
public class TestCalendar3 {
       public static void main(String[] args) {
              // 创建一个Calendar类型的对象
              Calendar c = Calendar.getInstance() ;
              System.out.println( c ); // 当前时间,可以通过get方法进行各个字段的获取
             
              // 通过设置Calendar中的各个常量的值,从而调整时间
              System.out.println( c.get( Calendar.YEAR )); // 2018
              c.set( Calendar.YEAR , 1995 ) ;
              /**
               * 通过 set 方法可以将指定字段的值,进行修改
               */
              System.out.println( c.get( Calendar.YEAR )); // 1995
              /**
               * 注意修改月份:
               * 当修改月份的时候,比如要修改成11月份,那么就需要传入 10
               * 也就是你修改的月份,进行减一操作,从而传入到参数中
               */
              c.set( Calendar.MONTH , 5 ) ;// 此时传入的是 5 , 那么其实表示的是 6月份
              c.set( Calendar.DATE , 1 ) ;
              c.set( Calendar.HOUR_OF_DAY , 14 ) ;
              c.set( Calendar.MINUTE , 39 ) ;
              c.set( Calendar.SECOND , 50 ) ;
              // 通过getTime返回一个java.util.Date对象
              Date d = c.getTime() ;
              /**
               * 此时可以发现时间进行了改变
               */
              System.out.println( d  ); // Thu Jun 01 14:39:50 GMT+08:00 1995 
       }
}
  • Calendar的方法
  • get & set 方法

get方法在上边已经描述过了,但是set方法有对应的重载,在这里进行说明

set​(int field, int value)
set​(int year, int month, int date)
set​(int year, int month, int date, int hourOfDay, int minute)
set​(int year, int month, int date, int hourOfDay, int minute, int second)

set方法主要就是对各个字段进行重新定义值,那么在之前使用过第一种方式,接下来来使用下面几种方法:

public class TestCalendar4 {
       public static void main(String[] args) {
              // 创建一个Calendar类型的对象
              Calendar c = Calendar.getInstance() ;
              c.set( Calendar.YEAR , 8 ) ;
              System.out.println( c.getTime() ); // Thu Nov 29 11:45:53 GMT+08:00 8
              /**
               * set(int year, int month, int date) :用于设置年月日
               * 设置月份的时候要注意进行操作(减一操作)
               */
              c.set( 1995 , (12-1) , 30 ) ;
              System.out.println( c.getTime() ); // Sat Dec 30 11:46:09 GMT+08:00 1995
              /**
               * set(int year, int month, int date, int hourOfDay, int minute):用于设置年月日时分
               */
              c.set( 2000 , 12-1 , 3 , 4 , 5  ) ;
              System.out.println( c.getTime() ); // Sun Dec 03 04:05:25 GMT+08:00 2000
             
              /**
               * set​(int year, int month, int date, int hourOfDay, int minute, int second):用于设置年月日时分秒
               */
              c.set( 2005 , 9-1 , 8 , 8 , 7, 0   ) ;
              System.out.println( c.getTime() ); // Thu Sep 08 08:07:00 GMT+08:00 2005
       }
}

那么这样get&set方法就清楚了。

  • after & before & compareTo & equals

这四个方法放在一起看,因为after和before在官方API的描述中主要是通过compareTo方法的返回值进行操作的,具体的操作可以查看java.util.Date中的方法。这里其实可以看一下源码。

// after 的源码
public boolean after(Object when) {
        return when instanceof Calendar
            && compareTo((Calendar)when) > 0;
    }
// before的源码
public boolean before(Object when) {
        return when instanceof Calendar
            && compareTo((Calendar)when) < 0;
    }
	
// compareTo的源码
public int compareTo(Calendar anotherCalendar) {
        return compareTo(getMillisOf(anotherCalendar));
    }

这里调用了compareTo的方法,其中有一个方法是采用getMillisOf这个方法,而getMillisOf主要是获取对应的毫秒值

// compareTo这个方法主要还是用毫秒值进行了比较
private int compareTo(long t) {
        long thisTime = getMillisOf(this);
        return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
    }

    private static long getMillisOf(Calendar calendar) {
        if (calendar.isTimeSet) {
            return calendar.time;
        }
        Calendar cal = (Calendar) calendar.clone();
        cal.setLenient(true);
        return cal.getTimeInMillis();
    }

而equals方法是重写来自父类java.lang.Object这个类,equals方法的源码如下:

@Override
    public boolean equals(Object obj) {
        if (this == obj) {// 如果当前对象就是要比较的对象,返回true
            return true;
        }
        try {
			// 尝试强制类型转换,然后进行操作
            Calendar that = (Calendar)obj;
			// 调用compareTo方法进行比较
            return compareTo(getMillisOf(that)) == 0 &&
                lenient == that.lenient &&
                firstDayOfWeek == that.firstDayOfWeek &&
                minimalDaysInFirstWeek == that.minimalDaysInFirstWeek &&
                zone.equals(that.zone);
        } catch (Exception e) {
            // Note: GregorianCalendar.computeTime throws
            // IllegalArgumentException if the ERA value is invalid
            // even it's in lenient mode.
        }
        return false;
    }
  • clear方法

clear方法有重载,具体描述如下 :

clear() : Sets all the calendar field values and the time value (millisecond offset from the Epoch) of this Calendar undefined. (设置未定义的所有日历字段值和时间值 (来自历元的毫秒偏移量)。)
clear​(int field) : Sets the given calendar field value and the time value (millisecond offset from the Epoch) of this Calendar undefined. (设置给定的日历字段值和未定义的此日历的时间值 (与历元的毫秒偏移量)。)

那么这两个方法主要是清除具体的字段等信息。示例如下:

public class TestCalendar5 {
       public static void main(String[] args) {
              Calendar c = Calendar.getInstance() ;
              c.set( 2005 , 9-1 , 8 , 8 , 7, 0   ) ;
              System.out.println( c.getTime() );  // Thu Sep 08 08:07:00 GMT+08:00 2005
//            c.clear();
//            System.out.println( c.getTime() ); // Thu Jan 01 00:00:00 GMT+08:00 1970
             
              c.clear( Calendar.YEAR );
              System.out.println( c.getTime() ); // Tue Sep 08 08:07:00 GMT+08:00 1970
             
       }
}

那么在这里就可以清楚的看到是将对应的字段进行处理,也就是设置到历元这个时间点上。

  • getActualMaximum​(int field) & getActualMinimum​(intfield)

官方API描述如下 :

	getActualMaximum​(int field): Returns the maximum value that the specified calendar field could have, given the time value of this Calendar.(在给定此日历的时间值的情况下, 返回指定日历字段可能具有的最大值。)
	getActualMinimum​(int field):Returns the minimum value that the specified calendar field could have, given the time value of this Calendar. (在给定此日历的时间值的情况下, 返回指定日历字段可能具有的最小值)

示例如下 :

public class TestCalendar6 {
       public static void main(String[] args) {
              Calendar c = Calendar.getInstance() ;
              System.out.println( c.getTime()  );
              int j = c.getActualMaximum( Calendar.DATE ) ;
              System.out.println( j );
              j = c.getActualMinimum( Calendar.DATE ) ;
              System.out.println( j );
              c.set( 2018 , 6 , 31 , 0 , 0 , 0 );
              System.out.println( c.getTime() );
              j = c.getActualMaximum( Calendar.DATE ) ;
              System.out.println( j );
              j = c.getActualMinimum( Calendar.DATE ) ;
              System.out.println( j );
       }
}
  • getAvailableCalendarTypes()

官方描述如下 :

getAvailableCalendarTypes():Returns an unmodifiable Set containing all calendar types supported by Calendar in the runtime environment.(返回包含运行时环境中日历支持的所有日历类型的不可修改的Set集合)

注意:是静态方法,也就是可以通过Calendar直接调用。示例如下

public class TestCalendar7 {
       public static void main(String[] args) {
              Set set = Calendar.getAvailableCalendarTypes() ;
              // 通过 foreach进行Set集合的迭代
              for( String s  : set ){
                     System.out.println( s );
              }
       }
}

这里需要看一下源码:

public static Set<String> getAvailableCalendarTypes() {
        return AvailableCalendarTypes.SET;
    }

那么在这里就直接返回了一个Set集合,那么可以查看一下这个Set集合中有什么东西

private static class AvailableCalendarTypes {
        private static final Set<String> SET;
        static {
			//这里就直接声明一个Set集合,然后将指定的值放入到Set集合中
            Set<String> set = new HashSet<>(3);
            set.add("gregory");
            set.add("buddhist");
            set.add("japanese");
            SET = Collections.unmodifiableSet(set);
        }
        private AvailableCalendarTypes() {
        }
    }

声明了一个静态内部类,其中存放了一些字符串,那么在这里就直接使用就可以了。但是可以明确的看到这里返回的就是这个Set集合中的数据。

  • getAvailableLocales()

官方描述如下:

Returns an array of all locales for which the getInstance methods of this class can return localized instances.(返回此类的 getInstance 方法可以为其返回本地化实例的所有区域设置的数组。)

示例如下:

public class TestCalendar8 {
       public static void main(String[] args) {
              Locale[] ls = Calendar.getAvailableLocales() ;
              for( Locale l : ls ){
                     System.out.println( l );
              }
       }
}

这里是一个静态方法,可以直接调用,那么这里返回的就是对应的Locale数组,其实是返回了可以在Calendar中进行设置的Locale数组。那么在源码中是如何操作的呢?源码如下:

public static synchronized Locale[] getAvailableLocales()
    {
        return DateFormat.getAvailableLocales();
    }

可以在这里清楚的看到是使用DateFormat的静态方法,那么可以进入去看一下:

public static Locale[] getAvailableLocales()
    {
        LocaleServiceProviderPool pool =
            LocaleServiceProviderPool.getPool(DateFormatProvider.class);
        return pool.getAvailableLocales();
    }

在这里又一次调用了LocaleServiceProviderPool的方法,那么继续进行查看:

public Locale[] getAvailableLocales() {
		// 声明了一个Set集合进行操作
        Set<Locale> locList = new HashSet<>();
		// 将可以获取到的Locale对象放入在Set集合中
        locList.addAll(getAvailableLocaleSet());
        // Make sure it all contains JRE's locales for compatibility.(为了兼容性,请确保它都包含JRE的区域设置。)
        locList.addAll(Arrays.asList(LocaleProviderAdapter.forJRE().getAvailableLocales()));
        Locale[] tmp = new Locale[locList.size()]; // 声明要给与set集合一样大的数组
        locList.toArray(tmp); //将set集合转成数组
        return tmp;// 返回这个数组 
    }

当然如果这里继续向下追的话,就比较深入了,有兴趣可以深入查看。

  • getCalendarType()

官方API描述如下 :

Returns the calendar type of this Calendar.(返回当前Calendar对象的日历类型)

示例如下:

public class TestCalendar9 {
       public static void main(String[] args) {
              Calendar c  = Calendar.getInstance() ;
              String s = c.getCalendarType() ;
              System.out.println( s );
       }
}

这个方法使用起来比较简单,在这里看一下源码:

public String getCalendarType() {
        return this.getClass().getName();
    }

在这里需要注意一下,这里表明是要获取一个具体的类型,但是如果要使用Calendar.class.getName()方法的话,这里返回的不是相同的对象,这里要明确一下。

  • getDisplayName​(int field, int style, Locale locale) & getDisplayNames​(intfield, int style, Locale locale)

官方描述如下:

Returns the string representation of the calendar field value in the given style and locale. If no string representation is applicable, null is returned. This method calls get(field) to get the calendar field value if the string representation is applicable to the given calendar field.(返回给定样式和区域设置中日历字段值的字符串表示形式。如果没有适用的字符串表示形式, 则返回 null。如果字符串表示形式适用于给定的日历字段, 则此方法调用 get (field) 以获取日历字段值。)

注意点:

参数:
	field - the calendar field for which the string representation is returned
	style - the style applied to the string representation; one of SHORT_FORMAT (SHORT), SHORT_STANDALONE, LONG_FORMAT (LONG), LONG_STANDALONE, NARROW_FORMAT, or NARROW_STANDALONE.
	locale - the locale for the string representation (any calendar types specified by locale are ignored)
异常信息:
	IllegalArgumentException - if field or style is invalid, or if this Calendar is non-lenient and any of the calendar fields have invalid values
	NullPointerException - if locale is null

在官方API中进行了参数的描述,所以这里要进行仔细的使用,还有对应的异常信息,要明确。示例如下:

public class TestCalendar10 {
       public static void main(String[] args) {
              Calendar c  = new GregorianCalendar() ;
              Locale locale = Locale.CHINA ;
              String s = c.getDisplayName(Calendar.HOUR, Calendar.SHORT_FORMAT, locale) ;
              System.out.println( s );
             
              Map map =  c.getDisplayNames( Calendar.JUNE, Calendar.ALL_STYLES, locale) ;
              System.out.println( map );
       }
}
  • getFirstDayOfWeek() & setFirstDayOfWeek​(int value)

官方描述如下:

	getFirstDayOfWeek() :Gets what the first day of the week is; e.g., SUNDAY in the U.S., MONDAY in France.(获取一周的第一天是什么;例如:, 周日在美国, 周一在法国。)
	setFirstDayOfWeek() :Sets what the first day of the week is; e.g., SUNDAY in the U.S., MONDAY in France.(设置一周的第一天是什么;例如:, 周日在美国, 周一在法国。)

示例如下 :

public class TestCalendar11 {
       public static void main(String[] args) {
              Calendar c = Calendar.getInstance() ;
              int j = c.getFirstDayOfWeek() ;
              System.out.println( j ); // 1
              c.setFirstDayOfWeek( 2 );
              j = c.getFirstDayOfWeek() ;
              System.out.println( j ); //2 
       }
}

那么在这里需要注意一下,这个仅仅是设置第一周的第一天是什么数值。

  • getGreatestMinimum​(int field) & getActualMaximum​(int field) & getActualMinimum​(int field) & getLeastMaximum( int field ) & getMinimum( int field )

这些方法放在这里,仅仅表示获取指定字段的最大值,或者最小值。官方描述如下:

	getGreatestMinimum​(int field):Returns the highest minimum value for the given calendar field of this Calendar instance.(返回此日历实例的给定日历字段的最高最小值。)
	getActualMaximum​(int field):Returns the maximum value that the specified calendar field could have, given the time value of this Calendar.(在给定此日历的时间值的情况下, 返回指定日历字段可能具有的最大值。)
	getActualMinimum​(int field):Returns the minimum value that the specified calendar field could have, given the time value of this Calendar.(在给定此日历的时间值的情况下, 返回指定的日历字段可能具有的最小值。)
	getLeastMaximum​(int field):Returns the lowest maximum value for the given calendar field of this Calendar instance.(返回此日历实例的给定日历字段的最小最大值。)
	getMinimum​(int field):Returns the minimum value for the given calendar field of this Calendar instance.(返回此日历实例的给定日历字段的最小值。)

示例如下:

public class TestCalendar11 {
       public static void main(String[] args) {
                Calendar c = Calendar.getInstance() ;
        	int i = c.getGreatestMinimum( Calendar.MONTH ) ;
        	System.out.println( i ); // 0 
        	i = c.getMinimum( Calendar.MONTH ) ;
        	System.out.println( i ); // 0 
		i = c.getLeastMaximum( Calendar.MONTH ) ;
		System.out.println( i ); // 11 
		i = c.getActualMinimum( Calendar.MONTH ) ;
		System.out.println( i ); // 0 
		i = c.getActualMaximum( Calendar.MONTH ) ;
		System.out.println( i ); // 11 
       }
}

在这个结果中可以看到,要么是返回了Calendar中指定字段的最大值,要么就是返回最小值,那么针对于月份来说,最小值就是0 , 那么最大值就是11 表示12月份。

  • getMinimalDaysInFirstWeek() & setMinimalDaysInFirstWeek​(int value)

官方API描述如下:

getMinimalDaysInFirstWeek():Gets what the minimal days required in the first week of the year are; e.g., if the first week is defined as one that contains the first day of the first month of a year, this method returns 1.(获取一年中第一周所需的最小天数;例如:, 如果第一周被定义为包含一年中第一个月的第一天, 则此方法返回1。)
setMinimalDaysInFirstWeek​(int value) :Sets what the minimal days required in the first week of the year are; For example, if the first week is defined as one that contains the first day of the first month of a year, call this method with value 1.(设置一年中第一周所需的最小天数;例如, 如果第一周被定义为包含一年中第一个月的第一天的一周, 则调用值为1的此方法。)

示例如下 :

public class TestCalendar13 {
       public static void main(String[] args) {
              Calendar c = Calendar.getInstance() ;
              int j = c.getMinimalDaysInFirstWeek() ;
              System.out.println( j ); //1
              c.setMinimalDaysInFirstWeek(123);
              System.out.println( c );
              j = c.getMinimalDaysInFirstWeek() ;
              System.out.println( j ); //123
       }
}

这个方法主要是设置或获取一年中第一周所需要的最小天数,默认的设置是1 ,虽然在这里设置了123这么一个值,实际上在设置的过程中只需要设置1~7即可。

  • getTime() & getTimeInMillis() & getTimeZone() & setTime​(Date date) & setTimeInMillis​(long millis) & setTimeZone​(TimeZone value)

这些方法主要是获取java.util.Date对象( getTime() ) 、获取毫秒值( getTimeInMillis() ) 和 获取时区(getTimeZone)以及这三个方法的set方法。 官方描述如下:

getTime() : Returns a Date object representing this Calendar's time value (millisecond offset from the Epoch").返回表示此日历的时间值的 date 对象 (从历元的毫秒偏移量 ")。
getTimeInMillis() : Returns this Calendar's time value in milliseconds.(返回此日历的时间值 (以毫秒为单位)。)
getTimeZone():Gets the time zone.(获取到时区)
setTime​(Date date) : Sets this Calendar's time with the given Date.(使用给定的日期设置此日历的时间)
setTimeInMillis​(long millis)  : Sets this Calendar's current time from the given long value.(从给定的长数值设置此日历的当前时间。)
setTimeZone​(TimeZone value):Sets the time zone with the given time zone value.(设置具有给定时区值的时区)

示例如下 :

public class TestCalendar14 {
       public static void main(String[] args) {
              Calendar c = Calendar.getInstance() ;
              System.out.println( c.getTime() ); // 返回一个java.util.Date对象
              System.out.println( c.getTimeInMillis() ); // 返回一个毫秒值
              System.out.println( c.getTimeZone() ); // 返回一个TimeZone对象
       }
}

那么对应的set方法分别是设置对应的属性,可以调到任意一个时间上。

  • getWeeksInWeekYear() & getWeekYear()

官方描述如下:

    getWeeksInWeekYear() :Returns the number of weeks in the week year represented by this Calendar.(返回此日历所表示的一周中的周数。)
    getWeekYear():Returns the week year represented by this Calendar.(返回此日历所表示的周年份。)

示例如下:

    public class TestCalendar14 {
           public static void main(String[] args) {
                  Calendar c = Calendar.getInstance() ;
                  System.out.println( c.getWeeksInWeekYear() );
                  System.out.println( c.getWeekYear() );
           }
    }

可以清楚的看到这里的返回的东西,getWeekYear返回了当前的年份,而getWeeksInWeekYear返回了这一年内有多少周。

  • hashCode()

用于计算当前Calendar对象的hashCode值,这个方法来自于父类java.lang.Object类,并重写该方法,具体的示例就不看了,源码如下:

public int hashCode() {
        // 'otheritems' represents the hash code for the previous versions.
        int otheritems = (lenient ? 1 : 0)
            | (firstDayOfWeek << 1)
            | (minimalDaysInFirstWeek << 4)
            | (zone.hashCode() << 7);
        long t = getMillisOf(this);
        return (int) t ^ (int)(t >> 32) ^ otheritems;
    }

通过源码可以看出,计算hash值的时候通过位运算进行了操作,从而计算出hash值。

  • isLenient() & isSet​(int field) & isWeekDateSupported() 官方API描述如下:
	isSet​(int field) :Determines if the given calendar field has a value set, including cases that the value has been set by internal fields calculations triggered by a get method call.( 确定给定的日历字段是否具有设置的值, 包括该值已由 get 方法调用触发的内部字段计算设置的情况。 )
	isLenient() :Tells whether date/time interpretation is to be lenient.(告诉日期/时间解释是否宽松)  
	isWeekDateSupported() :Returns whether this Calendar supports week dates.(返回此日历是否支持周日期。)

示例如下 :

public class TestCalendar14 {
	public static void main(String[] args) {
		Calendar c = Calendar.getInstance() ;
		boolean b = c.isLenient();
		System.out.println( b );
		b = c.isSet( Calendar.YEAR ) ;
		System.out.println( b );
		b = c.isWeekDateSupported();
		System.out.println( b ) ;
	}
}

这里主要是通过操作对应的字段来设置或者获取值的。

  • roll() 可以在这里看到roll方法有两个重载,其中一个方法是用abstract修饰的方法,表示一个抽象方法,而另一个则是一个默认的方法。官方API描述如下:
roll​(int field, boolean up) :Adds or subtracts (up/down) a single unit of time on the given time field without changing larger fields.( 在给定的时间字段上添加或减去单个时间单位, 而不更改较大的字段 )
roll​(int field, int amount) : Adds the specified (signed) amount to the specified calendar field without changing larger fields. ( 将指定的 (签名) 量添加到指定的日历字段, 而不更改较大的字段。 )

示例如下:

public class TestCalendar14 {
       public static void main(String[] args) {
              Calendar c = Calendar.getInstance() ;
              c.roll( Calendar.YEAR, false);
              System.out.println( c.getTime() );
              c.roll(Calendar.YEAR, 2222 );
              System.out.println( c.getTime() );
       }
}

toInstant() : 该方法主要是获取一个瞬间的一个点。

toString() : 重写来自于父类java.lang.Object类的方法。源码如下:

public String toString() {
        // NOTE: BuddhistCalendar.toString() interprets the string
        // produced by this method so that the Gregorian year number
        // is substituted by its B.E. year value. It relies on
        // "...,YEAR=<year>,..." or "...,YEAR=?,...".
        StringBuilder buffer = new StringBuilder(800);
        buffer.append(getClass().getName()).append('[');
        appendValue(buffer, "time", isTimeSet, time);
        buffer.append(",areFieldsSet=").append(areFieldsSet);
        buffer.append(",areAllFieldsSet=").append(areAllFieldsSet);
        buffer.append(",lenient=").append(lenient);
        buffer.append(",zone=").append(zone);
        appendValue(buffer, ",firstDayOfWeek", true, (long) firstDayOfWeek);
        appendValue(buffer, ",minimalDaysInFirstWeek", true, (long) minimalDaysInFirstWeek);
        for (int i = 0; i < FIELD_COUNT; ++i) {
            buffer.append(',');
            appendValue(buffer, FIELD_NAME[i], isSet(i), (long) fields[i]);
        }
        buffer.append(']');
        return buffer.toString();
    }

这里使用的是 StringBuffer 进行获取对应的操作之后,调用StringBuffer的toString方法进行返回指定的字符串。

java.sql.Date

这个日期是在Java连接数据库的时候需要使用的,也就是说是在数据库中进行使用的类型。java.sql.Date是直接继承java.util.Date的,那么也就是说java.util.Date类中存在的方法,java.sql.Date中也是存在的。java.sql.Date有两个构造方法,其中一个已经过时了,官方API描述如下:

Date​(long date):Constructs a Date object using the given milliseconds time value.(使用给定的毫秒值进行构造一个java.sql.Date对象)

示例如下:

public class TestSqlDate1 extends Thread {
       public static void main(String[] args) {
              long ms = System.currentTimeMillis() ;
              java.sql.Date d = new java.sql.Date( ms ) ;
       }
}

注意:java.sql.Date是集成来自于java.util.Date的,所以说在构造的时候,其实内部是直接调用父类的构造。

  • java.sql.Date的方法

这里看java.sql.Date的方法,这里要明确的是:已经被标记为过时的方法不再去看了,这是Java官方表示这些方法已经在当前版本不再适用。

  • setTime​(long date)

官方API描述如下:

Sets an existing Date object using the given milliseconds time value.( 给一个已经存在的Date对象设置指定的毫秒值)

示例如下:

public class TestSqlDate1 extends Thread {
       public static void main(String[] args) {
              long ms = System.currentTimeMillis() ;
              java.sql.Date d = new java.sql.Date( ms ) ;
              d.setTime( ms + 1 );
       }
}

使用起来比较简单,但是这个经常是存在于java.util.Date与java.sql.Date之间进行转换的操作。

  • valueOf​()

这个方法是静态方法,其中是有重载的存在,官方API描述如下:

valueOf​(String s)   :Converts a string in JDBC date escape format to a Date value.(将 jdbc 日期转义格式的字符串转换为 "日期" 值。)
valueOf​(LocalDate date) :Obtains an instance of Date from a LocalDate object with the same year, month and day of month value as the given LocalDate.(从具有相同的年、月和月日值作为给定的 "本地日期" 的 "本地日期" 对象中获取 "日期" 的实例。)

注意,valueOf( String s ) 会抛出IllegalArgumentException异常信息,表示如果给定的字符串不是yyyy-mm-dd的这种格式,那么会就跑出异常。valueOf​(LocalDate date) 会抛出空指针异常(NullPointerException) ,表示参数是一个null的时候会抛出这个异常信息。 示例如下:

public class TestSqlDate2 extends Thread {
       public static void main(String[] args) {
              String s = "2018-10-10";
              java.sql.Date d = java.sql.Date.valueOf( s ) ;
              System.out.println( d ); // 2018-10-10
       }
}

最后输出的意思是java.sql.Date的toString形式。其中的LocalDate放在后边去说。

  • toInstant() & toLocalDate() 这两个方法都是获取对应的对象,那么这两个方法使用起来比较简单,写在LocalDate与Instant这两个类中。
  • toString() 继承来自于java.lang.Object类,而java.sql.Date重写了这个方法,可以看一下源码:
public String toString () {
        int year = super.getYear() + 1900; // 获取年份,加上1900年,那么就是现在表示的年份
        int month = super.getMonth() + 1; // 获取月份  
        int day = super.getDate(); //获取指定的日期

        char buf[] = new char[10]; // 创建一个char数组,进而存放具体的字符
        formatDecimalInt(year, buf, 0, 4); // 调用方法,将年份放入到字符数组中,以下道理相同
        buf[4] = '-';
        Date.formatDecimalInt(month, buf, 5, 2); 
        buf[7] = '-';
        Date.formatDecimalInt(day, buf, 8, 2);

        return new String(buf);
    }

在源码中可以看到是对当前的对象进行了操作,而最后是使用new String的形式,从而返回一个字符串。

java.sql.Timestamp

首先来看官方的描述:

A thin wrapper around java.util.Date that allows the JDBC API to identify this as an SQL TIMESTAMP value. It adds the ability to hold the SQL TIMESTAMP fractional seconds value, by allowing the specification of fractional seconds to a precision of nanoseconds. A Timestamp also provides formatting and parsing operations to support the JDBC escape syntax for timestamp values.(java.util.Date周围的一个薄包装器,它允许JDBCAPI将其标识为SQL时间戳值。它增加了保持SQL时间戳小数秒值的能力,允许指定小数秒到纳秒的精度。时间戳还提供格式化和解析操作,以支持时间戳值的JDBC转义语法。)

这个类是直接继承java.util.Date类的,所以说java.util.Date类中有的方法,这个类也是存在的。而这个类的使用方式几乎和java.util.Date相同,可以来简单的看一下:

构造方法:

Timestamp​(long time):Constructs a Timestamp object using a milliseconds time value.(根据传入的毫秒值进行构建一个Timestamp对象)

方法:

after​(Timestamp ts) :Indicates whether this Timestamp object is later than the given Timestamp object.
before​(Timestamp ts):Indicates whether this Timestamp object is earlier than the given Timestamp object.
compareTo​(Timestamp ts):Compares this Timestamp object to the given Timestamp object.
compareTo​(Date o) :Compares this Timestamp object to the given Date object.
equals​(Object ts):Tests to see if this Timestamp object is equal to the given object.
equals​(Timestamp ts):Tests to see if this Timestamp object is equal to the given Timestamp object.
getTime()       :Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Timestamp object.
hashCode():Returns a hash code value for this object.
setTime​(long time) :Sets this Timestamp object to represent a point in time that is time milliseconds after January 1, 1970 00:00:00 GMT.
toInstant():Converts this Timestamp object to an Instant.
toLocalDateTime() :Converts this Timestamp object to a LocalDateTime.
toString()       :Formats a timestamp in JDBC timestamp escape format.
valueOf​(String s):Converts a String object in JDBC timestamp escape format to a Timestamp value.
valueOf​(LocalDateTime dateTime):Obtains an instance of Timestamp from a LocalDateTime object, with the same year, month, day of month, hours, minutes, seconds and nanos date-time value as the provided LocalDateTime.

可以发现以上的方法要么在java.util.Date中出现过,要么是在java.sql.Date中出现过,所以这些方法使用起来都比较简单,有几个新出的方法如下所示:

from​(Instant instant):Obtains an instance of Timestamp from an Instant object.( 将一个Instant对象转换成一个Timestamp对象)
getNanos():Gets this Timestamp object's nanos value.( 获取对应的纳秒值)
setNanos​(int n):Sets this Timestamp object's nanos field to the given value. (设置对应的纳秒值)

只有这几个方法没有见过,示例如下:

public class TestTimestamp extends Thread {
       public static void main(String[] args) {
              Timestamp t = new Timestamp( System.currentTimeMillis() ) ;
              System.out.println( t.getNanos() ); // 获取对应的纳秒值
              t.setNanos( 1200 ); // 设置指定的纳秒值
              System.out.println( t.getNanos() ); 
       }
}

因为Instant要放在后边写,所以这里的方法暂时先不看了。

java.sql.Time

java.sql.Time这个类是直接继承了java.util.Date这个类,所以java.util.Date中有的方法,在java.sql.Time这个类中都是存在的,并且都是可以使用的。 官方描述如下:

A thin wrapper around the java.util.Date class that allows the JDBC API to identify this as an SQL TIME value. The Time class adds formatting and parsing operations to support the JDBC escape syntax for time values. The date components should be set to the "zero epoch" value of January 1, 1970 and should not be accessed.(一个与 java.util.Date 类有关的瘦包装器 (thin wrapper),它允许 JDBC 将该类标识为 SQL TIME 值。Time 类添加格式化和解析操作以支持时间值的 JDBC 转义语法。应该将日期组件设置为 1970 年 1 月 1 日的 "zero epoch" 值并且不应访问该值。)

构造方法如下

Time​(long time):Constructs a Time object using a milliseconds time value.(使用一个指定的毫秒值构建一个Time对象)

可以发现,只要是继承java.util.Date类的子类,就会有传入毫秒值进行构造对象的方法。

具体的方法:都比较简单,可以自行查阅。

java.util.TimeZone

首先来看声明:

public abstract class TimeZone extends Object implements Serializable, Cloneable

这个类的声明,表示这个类是一个抽象类。实现了Serializable和cloneable接口,表示这个类是可以被复制的(Cloneable)和序列化的(Serializable)。

官方描述如下:

TimeZone represents a time zone offset, and also figures out daylight savings.Typically, you get a TimeZone using getDefault which creates a TimeZone based on the time zone where the program is running. For example, for a program running in Japan, getDefault creates a TimeZone object based on Japanese Standard Time.(TimeZone 表示时区偏移量,也可以计算夏令时.通常,使用 getDefault 获取 TimeZone,getDefault 基于程序运行所在的时区创建 TimeZone。例如,对于在日本运行的程序,getDefault 基于日本标准时间创建 TimeZone 对象。)

构造方法:(有且仅有一个构造方法)

TimeZone():Sole constructor.(唯一的构造)

但是之前写到,这个类是一个抽象类,也就是说没有办法通过构造进行创建对象,如果想要通过构造方法来创建这个类的对象的话,就会发现有大量的方法需要实现,所以这里如果要获取对应的TimeZone对象的话,可以采用静态方法的方式,或者是通过new 其子类的方式。

首先来看创建TimeZone的静态方法:

getDefault():Gets the default TimeZone of the Java virtual machine.(获取当前JVM默认的TimeZone对象)
getTimeZone​(ZoneId zoneId) :Gets the TimeZone for the given zoneId.(根据给定的zoneId获取一个TimeZone对象)
getTimeZone​(String ID) :Gets the TimeZone for the given ID. (根据给定的ID获取一个TimeZone对象)

示例如下:

public class TestTimeZone {
       public static void main(String[] args) {
              TimeZone tz = TimeZone.getDefault() ;
              System.out.println( tz ); // sun.util.calendar.ZoneInfo[id="GMT+08:00",offset=28800000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
              tz = TimeZone.getTimeZone("UTC");
              System.out.println( tz ); // sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
              ZoneId zid = ZoneId.systemDefault() ;
              tz = TimeZone.getTimeZone( zid ) ;
              System.out.println( tz ); // sun.util.calendar.ZoneInfo[id="GMT+08:00",offset=28800000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
       }
}

这样就可以获取到对应的TimeZone对象了。

其他的静态方法

getAvailableIDs():Gets all the available IDs supported.(获取受支持的所有可用 ID。)
getAvailableIDs​(int rawOffset):Gets the available IDs according to the given time zone offset in milliseconds.(根据给定的时区偏移量(以毫秒为单位)获取可用的 ID。)

这两个方法主要是获取对应的ID信息,示例如下:

public class TestTimeZone {
       public static void main(String[] args) {
              String[] ids = TimeZone.getAvailableIDs();
              for( String s : ids ){
                     System.out.println( s );
              }
              ids = TimeZone.getAvailableIDs( 1000 * 60 * 60 * 24 ) ;// 待研究
              System.out.println( Arrays.toString( ids ) );
       }
}
  • getDisplayName

这个方法有四个重载的方法,如下所示:

getDisplayName():Returns a long standard time name of this TimeZone suitable for presentation to the user in the default locale.( 返回适合于展示给默认区域的用户的时区名称。)
getDisplayName​(boolean daylight, int style) :Returns a name in the specified style of this TimeZone suitable for presentation to the user in the default locale.(返回此时区指定样式中的名称, 该名称适合在默认区域设置中演示给用户。)
getDisplayName​(boolean daylight, int style, Locale locale) :Returns a name in the specified style of this TimeZone suitable for presentation to the user in the specified locale.(返回此时区的指定样式中的名称, 该名称适合向指定区域设置中的用户演示。)
getDisplayName​(Locale locale):Returns a long standard time name of this TimeZone suitable for presentation to the user in the specified locale.(返回适合向指定区域设置中的用户演示的此时区的长标准时间名称。)

示例如下:

public class TestTimeZone {
       public static void main(String[] args) {
              TimeZone tz = TimeZone.getDefault() ;
              String name = tz.getDisplayName() ;
              System.out.println( name );
              tz = TimeZone.getTimeZone("UTC") ;
              name = tz.getDisplayName( true , TimeZone.SHORT );
              System.out.println( name );
              name = tz.getDisplayName( Locale.CANADA ) ;
              System.out.println( name );
              name = tz.getDisplayName( false , TimeZone.SHORT, Locale.CANADA ) ;
              System.out.println( name );
       }
}
  • getDSTSavings() 官方API描述如下:
Returns the amount of time to be added to local standard time to get local wall clock time.(返回要添加到本地标准时间以获取本地挂钟时间的时间量。)

示例如下:

public class TestTimeZone2 {
       public static void main(String[] args) {
              TimeZone tz = TimeZone.getTimeZone(Locale.CANADA.toString() ) ;
              int j = tz.getDSTSavings();
              System.out.println( j );
       }
}
  • getID()

官方描述如下:

Gets the ID of this time zone.(获取这个TimeZone的id)

示例如下:

public class TestTimeZone2 {
       public static void main(String[] args) {
              TimeZone tz = TimeZone.getTimeZone("GMT") ;
              String s = tz.getID() ;
              System.out.println( s );
       }
}
  • setDefault​(TimeZone zone)

官方描述如下:

Sets the TimeZone that is returned by the getDefault method.(设置由 getDefault 方法返回的 TimeZone。)

示例如下:

public class TestTimeZone2 {
       public static void main(String[] args) {
              TimeZone.setDefault( TimeZone.getTimeZone("GMT+12:00"));
              TimeZone tz = TimeZone.getDefault() ;
              System.out.println( tz );
       }
}

关于其他的方法,这里就不做过多的介绍了。

java.util.Locale

在API中的描述如下:

public final class Locale  extends Object implements Cloneable, Serializable

可以看到是用final修饰的,也就是是没有子类的,这点要注意。

构造方法:

Locale​(String language) :Construct a locale from a language code.( 根据语言代码构造一个语言环境。)
Locale​(String language, String country):Construct a locale from language and country.(根据语言和国家/地区构造一个语言环境。)
Locale​(String language, String country, String variant):Construct a locale from language, country and variant.(根据语言、国家/地区和变量构造一个语言环境。)

当然,内部有对应的字段用来表示对应的Locale对象,如下所示:

CANADA、CANADA_FRENCH、CHINA、CHINESE、ENGLISH……

示例如下:

/**
 * 测试构造方法
 */
public class TestLocale {
       public static void main(String[] args) {
              Locale l = new Locale("中文") ;
              System.out.println( l );
              l = new Locale("中文" , "洪荒") ;
              System.out.println( l );
              l = new Locale("中文" , "上古" , "夏朝" ) ;
              System.out.println( l );
              l = new Locale("zh") ;
              System.out.println( l );
              l = new Locale("zh" , "cn") ;
              System.out.println( l );
              l = new Locale("zh" , "cn" , "TW" ) ;
              System.out.println( l );
       }
}

通过构造方法可以创建一个Locale对象,那么也可以通过常量来构建对应的Locale对象,示例如下:

public class TestLocale {
    public static void main(String[] args) {
        Locale locale = Locale.CANADA ;
        System.out.println( locale ); // en_CA
    }
}

这样的话,就可以使用常量进行构建Locale对象。当然,依旧可以使用静态方法从而构建Locale方法

  • Locale中的方法

这里只看部分的方法,用几个例子就可以说明,示例如下:

/**
* 1、获得Locale实例
* Locale( String language) : 根据语言代码构造一个语言环境
* Locale( String language, String conuntry ):根据语言和国家/地区构造
一个语言环境
* static Locale getDefault() : 获得默认的Locale实例
* 2、查看这个实例中的信息
* String getCountry() : 获得到国家/地区的编码 ISO3166两字母编码
* String getLanguage() : 获得语言的编码 编码的标准ISO639编码
* String getDisplayCountry():返回适合向用户显示的语言环境国家/地区
名。
* String getDisplayLanguage() 返回适合向用户显示的语言环境语言名
称。
* String getDisplayCountry(Locale inLocale) 该Locale对象对应的国
家或地区名称在inLocale那里对应的名称
* String getDisplayLanguage(Locale inLocale) 该Locale对象对应的语言
在inLocale那里对应的名称
* String getDisplayName() 返回适合向用户显示的语言环境名
* String getDisplayName(Locale inLocale) 返回适合向用户显示的语言环
境名
* 3、当前JVM支持的所有的Locale
* static Locale[] getAvailableLocales() 返回所有已安装语言环境
的数组。
* String getVariant()
*/
public class TestLocale1 {
	public static void main(String[] args) {
		Locale = Locale.getDefault();
		System.out.println("国家或地区代码:"+ locale.getCountry());
		 System.out.println("语言代码:"+ locale.getLanguage());
		System.out.println("你所在的地方,这个国家或地区的名称是:"+
		locale.getDisplayCountry());
		System.out.println("你所在的地方,这个国家或地区使用的语言名称是:"+
		locale.getDisplayLanguage());
		System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`");
		Locale[] locales = Locale.getAvailableLocales();
		for (int i = 0; i < locales.length; i++) {
			Locale lo = locales[i];
			System.out.print(lo.getCountry() + "\t");
			System.out.print(lo.getLanguage() + "\t");
			System.out.println(lo.getVariant() + "\t");
		}
	}
}
public class TestLocale2 {
	public static void main(String[] args) {
		final Locale = Locale.getDefault();
		System.out.println("国家或地区代码:"+ locale.getCountry());
		System.out.println("语言代码:"+ locale.getLanguage());
		System.out.println("你所在的地方,这个国家或地区的名称是:"+ locale.getDisplayCountry());
		System.out.println("你所在的地方,这个国家或地区使用的语言名称是:"+ locale.getDisplayLanguage());
		final Locale enUS = new Locale("en","US");
		System.out.println("你所在的地方,这个国家或地区的名称是:"+ enUS.getDisplayCountry());
		System.out.println("你所在的地方,这个国家或地区使用的语言名称是:"+ enUS.getDisplayLanguage());
	}
}
import java.util.Locale;
/**
* 获得当前默认的Locale 对象
* 看一下 这个默认的Locale对象,在不同的国家或地区分别叫什么名称
*/
public class TestLocale3 {
	public static void main(String[] args) {
		final Locale = Locale.getDefault();
		final Locale[] locales = Locale.getAvailableLocales();
		for (int i = 0; i < locales.length; i++) {
		Locale o = locales[i];// 获得所有国家和地区中的一个对象
		System.out.print(o.getDisplayCountry()+"\t");
		System.out.print("Country:"+locale.getDisplayCountry( o ) +"\t\t");
		System.out.println("Language:"+locale.getDisplayLanguage( o ) );
		}
	}
}
import java.util.Locale;
/**
* Locale 的信息
*/
public class TestLocale4 {
	public static void main(String[] args) {
		Locale = Locale.getDefault();
		System.out.println("国家或地区代码:"+ locale.getCountry());
		System.out.println("语言代码:"+ locale.getLanguage());
		System.out.println("你所在的地方,这个国家或地区的名称是:"+locale.getDisplayCountry());
		System.out.println("你所在的地方,这个国家或地区使用的语言名称是:"+ locale.getDisplayLanguage());
		System.out.println("国家或地区对应的名称:"+locale.getDisplayName());
	}
}

这里是将几个类放在了一起,那么其余的方法可以自行查阅。

那么TimeZone与Locale一起使用的方式如下所示:

import java.util.Locale;
import java.util.TimeZone;
public class LocaleTimeZone {
	public static void main(String[] args) {
		TimeZone tz = TimeZone.getDefault();
		Locale = Locale.getDefault();
		System.out.println(tz.getDisplayName());
		System.out.println(tz.getDisplayName(locale));
		 locale = new Locale("en","US");
		System.out.println(tz.getDisplayName(locale));
	}
}

java.text.DateFormat & java.text.SimpleDateFormat

这里主要描述的就是日期格式化,也就是表示日期按照什么样子的格式进行处理。在这里仅仅描述使用方式,不考虑源码实现。

DateFormat

这个类表示对应的日期格式化,主要是继承来自于java.text.Format这个类,但是DateFormat这个类是一个抽象类,那么在抽象类中是没有办法进行new DateFormat的操作,所以这里可以采用静态方法或new 子类的方式进行初始化操作。

  • 静态方法初始化

因为使用静态方法进行初始化的时候,会有很多方法,所以这里可以考虑全部查看。但是具体使用的时候,要根据情况来使用。

	getDateInstance():Gets the date formatter with the default formatting style for the default FORMAT locale.
	getDateInstance​(int style):Gets the date formatter with the given formatting style for the default FORMAT locale.
	getDateInstance​(int style, Locale aLocale):Gets the date formatter with the given formatting style for the given locale.
	getDateTimeInstance():Gets the date/time formatter with the default formatting style for the default FORMAT locale.
	getDateTimeInstance​(int dateStyle, int timeStyle):Gets the date/time formatter with the given date and time formatting styles for the default FORMAT locale.
	getDateTimeInstance​(int dateStyle, int timeStyle, Locale aLocale):Gets the date/time formatter with the given formatting styles for the given locale.
	getInstance():Get a default date/time formatter that uses the SHORT style for both the date and the time.
	getTimeInstance():Gets the time formatter with the default formatting style for the default FORMAT locale.
	getTimeInstance​(int style):Gets the time formatter with the given formatting style for the default FORMAT locale.
	getTimeInstance​(int style, Locale aLocale):Gets the time formatter with the given formatting style for the given locale.

可以看到有这么多的静态方法是可以调用的,但是针对于静态方法来说,其实本质依旧是创建子类。那么在这里,使用格式化一个日期对象,来查看这些方法是有什么不同的情况产生。

public class DateFormatTest {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date() ;

        DateFormat dateFormat = DateFormat.getDateInstance() ;
        String dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getDateInstance( DateFormat.SHORT   ) ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getDateInstance( DateFormat.MEDIUM , Locale.ENGLISH ) ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getDateTimeInstance() ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getDateTimeInstance( DateFormat.MEDIUM , DateFormat.SHORT ) ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getDateTimeInstance( DateFormat.LONG , DateFormat.SHORT , Locale.ENGLISH ) ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getInstance() ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getTimeInstance() ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getTimeInstance( DateFormat.MEDIUM ) ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

        dateFormat = DateFormat.getTimeInstance( DateFormat.MEDIUM , Locale.ENGLISH ) ;
        dateString  = dateFormat.format( date ) ;
        System.out.println( dateString );

    }
}

那么在这里可以明确的看到将所有的静态方法全部执行了一遍,从而可以发现格式尽管都不太一样,但是具体的方式都是可以理解的。

那么在这里使用了一个方法,是format 方法,这个方法主要是将java.util.Date转换成java.lang.String类型。当然也有将String类型转换成java.util.Date类型的方法。

  • format() 与 parse()

那么在这里介绍主要的两个方法,也就是String类型与java.util.Date之间相互转换的方法。具体示例如下:

public class DateFormatTest2 {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date() ;

        DateFormat dateFormat = DateFormat.getDateInstance() ;
        System.out.println( dateFormat.format( date ) ) ;

        String dateString = "2019年一月一日" ;
        try {
            /**
             * 在这里是有异常信息的,因为如果要转换的话,那么就要按照指定的格式进行转换
             * 如果格式不对的话,那么就转换失败.
             * 此时这里是转换失败的 如果改成 : 2019年1月1日 就不会失败了
             * */
            date = dateFormat.parse( dateString ) ;
            System.out.println( date );
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

在这里查看了具体的操作,可是在实际中并不会这样去使用。会使用java.text.DateFormat的子类java.text.SimpleDateFormat来进行操作。

  • SimpleDateFormat

这个类是DateFormat 的子类,那么也是可以通过直接new 的方法进行使用。但是有四个构造方法,如下所示:

	SimpleDateFormat():Constructs a SimpleDateFormat using the default pattern and date format symbols for the default FORMAT locale.
	SimpleDateFormat​(String pattern):Constructs a SimpleDateFormat using the given pattern and the default date format symbols for the default FORMAT locale.
	SimpleDateFormat​(String pattern, DateFormatSymbols formatSymbols):Constructs a SimpleDateFormat using the given pattern and date format symbols.
	SimpleDateFormat​(String pattern, Locale locale):Constructs a SimpleDateFormat using the given pattern and the default date format symbols for the given locale.

但是最常时间使用的是前面两个构造,但是此次示例中会将四种构造都进行使用。因为SimpleDateFormat是DateFormat的子类,所以这里的方法就不做过多的介绍了,仅仅查看parse和format两个方法。

public class DateFormatTest3 {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date() ;
        DateFormat df = new SimpleDateFormat() ;
        System.out.println( df.format( date ) ) ;
        /**
         * 这里传入的字符串表示指定的模式,那么具体的模式可以在API文档中进行查看
         */
        df = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS") ;
        System.out.println( df.format( date ));

        df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" , DateFormatSymbols.getInstance(Locale.CHINESE) ) ;
        System.out.println( df.format( date ) ) ;

        df = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" , Locale.CHINESE ) ;
        System.out.println( df.format( date ) ) ; 
    }
}

可以发现在使用具体的构造的时候,一般都会传入一个字符串。此时的字符串表示的是要转换的模版,那么在这里就表示按照这种模版进行转换,当调用format或parse 的时候,会按照指定的模版进行解析或转换。如果在调用parse 的时候,传入的字符串与指定的模版不是一种类型的话,那么就会抛出转换异常。

那么基础的时间就写这么多,下一篇博客写的就是jdk1.8之后出现的时间类。

转载于:https://my.oschina.net/lujiapeng/blog/2995823

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值