Java日期时间(Date/Time)(附Date.java源码)

Java日期时间(Date/Time)  (附Date.java源码)

Java在java.util包中提供了Date类,这个类封装了当前的日期和时间。

Date类支持两种构造函数。第一个构造函数初始化对象的当前日期和时间。

Date( )

下面的构造函数接受一个参数等于自午夜,1970年1月1日起已经过的毫秒数

Date(long millisec)

一旦有一个日期对象,可以调用以下任何一种支持的方法和时间:

SN 方法和描述
1 boolean after(Date date)
如果调用Date对象包含或晚于指定的日期则返回true,否则,返回false。
2 boolean before(Date date)
如果调用Date对象包含或早于日期指定的日期返回true,否则,返回false。
3 Object clone( )
重复调用Date对象。
4 int compareTo(Date date)
比较日期的调用对象的值。如果这两个值相等返回0。如果调用对象是早于日期返回一个负值。如果调用对象最迟日期返回正值。
5 int compareTo(Object obj)
操作以相同的compareTo(Date) 如果obj是一个类日期。否则,它会抛出一个ClassCastException。
6 boolean equals(Object date)
如果调用Date对象包含相同的时间及日期指定日期则返回true,否则,返回false。
7 long getTime( )
返回自1970年1月1日起已经过的毫秒数。
8 int hashCode( )
返回调用对象的哈希代码。
9 void setTime(long time)
设置所指定的时间,这表示经过时间以毫秒为单位,1970年1月1日从午夜的时间和日期
10 String toString( )
调用Date对象转换为字符串,并返回结果。

获取当前日期和时间

在Java中容易得到当前的日期和时间。可以使用一个简单的Date对象的toString()方法,如下所示打印当前日期和时间:

import java.util.Date;
  
public class DateDemo {
   public static void main(String args[]) {
       // Instantiate a Date object
       Date date = new Date();
        
       // display time and date using toString()
       System.out.println(date.toString());
   }
}

这将产生以下结果:

Mon May 04 09:51:52 CDT 2009

日期比较:

有以下三种方式来比较两个日期:

  • 可以使用getTime() 来获得自1970年1月1日午夜十二时,起已经过的毫秒数,然后比较两个对象的值。

  • 可以使用 before( ), after( ), and equals( ),由于本月12日来的18日前,例如, new Date(99, 2, 12).before(new Date (99, 2, 18)) 返回 true。

  • 可以使用compareTo()方法,这是由Comparable接口定义和日期执行。

使用SimpleDateFormat格式化日期:

SimpleDateFormat是一个具体的类,用于格式化和分析日期的语言环境敏感的方式。 SimpleDateFormat先选择任何用户定义的模式为日期时间格式。例如:

import java.util.*;
import java.text.*;

public class DateDemo {
   public static void main(String args[]) {

      Date dNow = new Date( );
      SimpleDateFormat ft = 
      new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");

      System.out.println("Current Date: " + ft.format(dNow));
   }
}

这将产生以下结果:

Current Date: Sun 2004.07.18 at 04:14:09 PM PDT

简单的DateFormat格式代码:

要指定时间格式,使用时间模式字符串。在这个模式中,所有的ASCII字母被保留为模式字母,其定义如下:

Character 描述 Example
G Era designator AD
y Year in four digits 2001
M Month in year July or 07
d Day in month 10
h Hour in A.M./P.M. (1~12) 12
H Hour in day (0~23) 22
m Minute in hour 30
s Second in minute 55
S Millisecond 234
E Day in week Tuesday
D Day in year 360
F Day of week in month 2 (second Wed. in July)
w Week in year 40
W Week in month 1
a A.M./P.M. marker PM
k Hour in day (1~24) 24
K Hour in A.M./P.M. (0~11) 10
z Time zone Eastern Standard Time
' Escape for text Delimiter
" Single quote `

用printf格式化日期:

日期和时间格式用printf方法可以非常轻松地做到。您可以使用两个字母的格式,从t和在下面给出的表格中的其中一个字母结束。例如:

import java.util.Date;

public class DateDemo {

  public static void main(String args[]) {
     // Instantiate a Date object
     Date date = new Date();

     // display time and date using toString()
     String str = String.format("Current Date/Time : %tc", date );

     System.out.printf(str);
  }
}

这将产生以下结果:

Current Date/Time : Sat Dec 15 16:37:57 MST 2012

如果提供日期多次格式化是一种比较笨的做法。一个格式字符串可以指示要格式化的参数的索引。

索引必须紧跟在%,并必须由$终止。例如:

import java.util.Date;
  
public class DateDemo {

   public static void main(String args[]) {
       // Instantiate a Date object
       Date date = new Date();
        
       // display time and date using toString()
       System.out.printf("%1$s %2$tB %2$td, %2$tY", 
                         "Due date:", date);
   }
}

这将产生以下结果:

Due date: February 09, 2004

或者,也可以使用<标志。则表示相同的参数,根据前述格式规范,应再次使用。例如:

import java.util.Date;
  
public class DateDemo {

   public static void main(String args[]) {
       // Instantiate a Date object
       Date date = new Date();
        
       // display formatted date
       System.out.printf("%s %tB %<te, %<tY", 
                         "Due date:", date);
   }
}

这将产生以下结果:

Due date: February 09, 2004

日期和时间转换字符:

字符 描述 例子
c Complete date and time Mon May 04 09:51:52 CDT 2009
F ISO 8601 date 2004-02-09
D U.S. formatted date (month/day/year) 02/09/2004
T 24-hour time 18:05:19
r 12-hour time 06:05:19 pm
R 24-hour time, no seconds 18:05
Y Four-digit year (with leading zeroes) 2004
y Last two digits of the year (with leading zeroes) 04
C First two digits of the year (with leading zeroes) 20
B Full month name February
b Abbreviated month name Feb
m Two-digit month (with leading zeroes) 02
d Two-digit day (with leading zeroes) 03
e Two-digit day (without leading zeroes) 9
A Full weekday name Monday
a Abbreviated weekday name Mon
j Three-digit day of year (with leading zeroes) 069
H Two-digit hour (with leading zeroes), between 00 and 23 18
k Two-digit hour (without leading zeroes), between 0 and 23 18
I Two-digit hour (with leading zeroes), between 01 and 12 06
l Two-digit hour (without leading zeroes), between 1 and 12 6
M Two-digit minutes (with leading zeroes) 05
S Two-digit seconds (with leading zeroes) 19
L Three-digit milliseconds (with leading zeroes) 047
N Nine-digit nanoseconds (with leading zeroes) 047000000
P Uppercase morning or afternoon marker PM
p Lowercase morning or afternoon marker pm
z RFC 822 numeric offset from GMT -0800
Z Time zone PST
s Seconds since 1970-01-01 00:00:00 GMT 1078884319
Q Milliseconds since 1970-01-01 00:00:00 GMT 1078884319047

有相关的日期和时间等有用的类。欲了解更多详细信息,可以参考Java标准文档。

解析字符串到日期:

SimpleDateFormat类有一些额外的方法,如parse(),它试图根据存储在给定SimpleDateFormat 的对象的格式来分析字符串。例如:

import java.util.*;
import java.text.*;
  
public class DateDemo {

   public static void main(String args[]) {
      SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); 

      String input = args.length == 0 ? "1818-11-11" : args[0]; 

      System.out.print(input + " Parses as "); 

      Date t; 

      try { 
          t = ft.parse(input); 
          System.out.println(t); 
      } catch (ParseException e) { 
          System.out.println("Unparseable using " + ft); 
      }
   }
}

上述程序的运行示例将产生以下结果:

$ java DateDemo
1818-11-11 Parses as Wed Nov 11 00:00:00 GMT 1818
$ java DateDemo 2007-12-01
2007-12-01 Parses as Sat Dec 01 00:00:00 GMT 2007

休眠一会:

可以在任何期间的时间休眠从一个毫秒。例如,下面的程序会休眠10秒:

import java.util.*;
  
public class SleepDemo {
   public static void main(String args[]) {
      try { 
         System.out.println(new Date( ) + "\n"); 
         Thread.sleep(5*60*10); 
         System.out.println(new Date( ) + "\n"); 
      } catch (Exception e) { 
          System.out.println("Got an exception!"); 
      }
   }
}

这将产生以下结果:

Sun May 03 18:04:41 GMT 2009

Sun May 03 18:04:51 GMT 2009

测量执行时间:

有时候,可能需要测量的时间点以毫秒为单位。因此,让我们再一次重新写上面的例子:

import java.util.*;
  
public class DiffDemo {

   public static void main(String args[]) {
      try {
         long start = System.currentTimeMillis( );
         System.out.println(new Date( ) + "\n");
         Thread.sleep(5*60*10);
         System.out.println(new Date( ) + "\n");
         long end = System.currentTimeMillis( );
         long diff = end - start;
         System.out.println("Difference is : " + diff);
      } catch (Exception e) {
         System.out.println("Got an exception!");
      }
   }
}

这将产生以下结果:

Sun May 03 18:16:51 GMT 2009

Sun May 03 18:16:57 GMT 2009

Difference is : 5993

GregorianCalendar 类:

GregorianCalendar是一个具体的实现一个日历类实现正常的公历。本教程中不讨论Calendar类,可以看看标准Java文档。

Calendar的getInstance()方法返回与当前日期和时间默认语言环境和时区初始化一个GregorianCalendar。 GregorianCalendar中定义了两个字段:AD和BC。这些代表在公历中定义的两个时代。

也有几个构造函数的GregorianCalendar对象:

SN  构造函数描述
1 GregorianCalendar() 
默认的GregorianCalendar构造使用当前时间的默认时区与默认语言环境。
2 GregorianCalendar(int year, int month, int date) 
构造一个GregorianCalendar用给定的日期的默认时区设置默认的语言环境。
3 GregorianCalendar(int year, int month, int date, int hour, int minute) 
构造一个GregorianCalendar用给定的日期和时间设置为与默认语言环境的默认时区。
4 GregorianCalendar(int year, int month, int date, int hour, int minute, int second) 
构造一个GregorianCalendar用给定的日期和时间设置为与默认语言环境的默认时区。
5 GregorianCalendar(Locale aLocale) 
构建了基于当前时间与给定语言环境的默认时区一个GregorianCalendar。
6 GregorianCalendar(TimeZone zone) 
构建了基于当前时间,使用默认的语言环境在给定的时区一个GregorianCalendar。
7 GregorianCalendar(TimeZone zone, Locale aLocale) 
构建了基于当前时间与给定语言环境的给定时区一个GregorianCalendar。

这里是由GregorianCalendar类提供一些有用的支持方法的列表:

SN 方法和描述
1 void add(int field, int amount) 
添加指定(有符号的)时间量,以给定的时间字段,基于日历的规则。
2 protected void computeFields() 
将UTC转换为毫秒时间字段值.
3 protected void computeTime() 
覆盖日历转换时间域值为UTC的毫秒.
4 boolean equals(Object obj) 
比较这个GregorianCalendar的一个对象引用.
5 int get(int field) 
获取给定时间域的值.
6 int getActualMaximum(int field) 
返回该字段可能的最大值,考虑到当前的日期.
7 int getActualMinimum(int field) 
返回该字段可以具有的最低值,给定当前的日期.
8 int getGreatestMinimum(int field) 
对于给定的字段中返回高最低值(如果有变化).
9 Date getGregorianChange() 
获取公历更改日期.
10 int getLeastMaximum(int field) 
对于给定的字段返回最低的最大值(如果有变化).
11 int getMaximum(int field) 
返回给定字段中的最大值.
12 Date getTime()
获取日历的当前时间.
13 long getTimeInMillis() 
获取日历的当前时间长.
14 TimeZone getTimeZone() 
获取时区.
15 int getMinimum(int field) 
返回给定字段中的最小值.
16 int hashCode() 
重写hashCode.
17 boolean isLeapYear(int year)
确定给定年份是闰年.
18 void roll(int field, boolean up) 
加上或减去(上/下)的时间在给定的时间字段一个单元,不更改更大的字段.
19 void set(int field, int value) 
设置时间字段与给定值.
20 void set(int year, int month, int date) 
设置为年,月,日的值.
21 void set(int year, int month, int date, int hour, int minute) 
设置为年,月,日,小时和分钟值.
22 void set(int year, int month, int date, int hour, int minute, int second) 
设置为字段的年,月,日,小时,分钟和秒的值.
23 void setGregorianChange(Date date) 
设置GregorianCalendar更改日期.
24 void setTime(Date date) 
设置日历的当前时间与给定日期.
25 void setTimeInMillis(long millis) 
从给定long值设置日历的当前时间.
26 void setTimeZone(TimeZone value) 
将时区设置与给定的时区值.
27 String toString() 
返回此日历的字符串表示形式.

例子:

import java.util.*;
  
public class GregorianCalendarDemo {

   public static void main(String args[]) {
      String months[] = {
      "Jan", "Feb", "Mar", "Apr",
      "May", "Jun", "Jul", "Aug",
      "Sep", "Oct", "Nov", "Dec"};
      
      int year;
      // Create a Gregorian calendar initialized
      // with the current date and time in the
      // default locale and timezone.
      GregorianCalendar gcalendar = new GregorianCalendar();
      // Display current time and date information.
      System.out.print("Date: ");
      System.out.print(months[gcalendar.get(Calendar.MONTH)]);
      System.out.print(" " + gcalendar.get(Calendar.DATE) + " ");
      System.out.println(year = gcalendar.get(Calendar.YEAR));
      System.out.print("Time: ");
      System.out.print(gcalendar.get(Calendar.HOUR) + ":");
      System.out.print(gcalendar.get(Calendar.MINUTE) + ":");
      System.out.println(gcalendar.get(Calendar.SECOND));
      
      // Test if the current year is a leap year
      if(gcalendar.isLeapYear(year)) {
         System.out.println("The current year is a leap year");
      }
      else {
         System.out.println("The current year is not a leap year");
      }
   }
}

这将产生以下结果:

Date: Apr 22 2009
Time: 11:25:27
The current year is not a leap year

在Calendar类中的常量的完整列表,可以参考标准的Java文档。


附录 Date.java
/*************************************************************************
 *  Compilation:  javac Date.java
 *  Execution:    java Date
 *
 *  An immutable data type for dates.
 *
 *************************************************************************/

/**
 *  The <tt>Date</tt> class is an immutable data type to encapsulate a
 *  date (day, month, and year).
 *  <p>
 *  For additional documentation, see <a href="/algs4/12oop">Section 1.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *  @author Robert Sedgewick
 *  @author Kevin Wayne
 */
public class Date implements Comparable<Date> {
    private static final int[] DAYS = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

    private final int month;   // month (between 1 and 12)
    private final int day;     // day   (between 1 and DAYS[month]
    private final int year;    // year

   /**
     * Initializes a new date from the month, day, and year.
     * @param month the month (between 1 and 12)
     * @param day the day (between 1 and 28-31, depending on the month)
     * @param year the year
     * @throws IllegalArgumentException if the date is invalid
     */
    public Date(int month, int day, int year) {
        if (!isValid(month, day, year)) throw new IllegalArgumentException("Invalid date");
        this.month = month;
        this.day   = day;
        this.year  = year;
    }

    /**
     * Initializes new date specified as a string in form MM/DD/YYYY.
     * @param date the string representation of the date
     * @throws IllegalArgumentException if the date is invalid
     */
    public Date(String date) {
        String[] fields = date.split("/");
        if (fields.length != 3) {
            throw new IllegalArgumentException("Invalid date");
        }
        month = Integer.parseInt(fields[0]);
        day   = Integer.parseInt(fields[1]);
        year  = Integer.parseInt(fields[2]);
        if (!isValid(month, day, year)) throw new IllegalArgumentException("Invalid date");
    }

    /**
     * Return the month.
     * @return the month (an integer between 1 and 12)
     */
    public int month() {
        return month;
    }

    /**
     * Return the day.
     * @return the day (an integer between 1 and 31)
     */
    public int day() {
        return day;
    }

    /**
     * Return the year.
     * @return the year
     */
    public int year() {
        return year;
    }


    // is the given date valid?
    private static boolean isValid(int m, int d, int y) {
        if (m < 1 || m > 12)      return false;
        if (d < 1 || d > DAYS[m]) return false;
        if (m == 2 && d == 29 && !isLeapYear(y)) return false;
        return true;
    }

    /**
     * Is year y a leap year?
     * @return true if y is a leap year; false otherwise
     */
    private static boolean isLeapYear(int y) {
        if (y % 400 == 0) return true;
        if (y % 100 == 0) return false;
        return y % 4 == 0;
    }

    /**
     * Returns the next date in the calendar.
     * @return a date that represents the next day after this day
     */
    public Date next() {
        if (isValid(month, day + 1, year))    return new Date(month, day + 1, year);
        else if (isValid(month + 1, 1, year)) return new Date(month + 1, 1, year);
        else                                  return new Date(1, 1, year + 1);
    }

    /**
     * Is this date after b?
     * @return true if this date is after date b; false otherwise
     */
    public boolean isAfter(Date b) {
        return compareTo(b) > 0;
    }

    /**
     * Is this date before b?
     * @return true if this date is before date b; false otherwise
     */
    public boolean isBefore(Date b) {
        return compareTo(b) < 0;
    }

    /**
     * Compare this date to that date.
     * @return { a negative integer, zero, or a positive integer }, depending
     *    on whether this date is { before, equal to, after } that date
     */
    public int compareTo(Date that) {
        if (this.year  < that.year)  return -1;
        if (this.year  > that.year)  return +1;
        if (this.month < that.month) return -1;
        if (this.month > that.month) return +1;
        if (this.day   < that.day)   return -1;
        if (this.day   > that.day)   return +1;
        return 0;
    }

    /**
     * Return a string representation of this date.
     * @return the string representation in the foramt MM/DD/YYYY
     */
    public String toString() {
        return month + "/" + day + "/" + year;
    }

    /**
     * Is this date equal to x?
     * @return true if this date equals x; false otherwise
     */
    public boolean equals(Object x) {
        if (x == this) return true;
        if (x == null) return false;
        if (x.getClass() != this.getClass()) return false;
        Date that = (Date) x;
        return (this.month == that.month) && (this.day == that.day) && (this.year == that.year);
    }

    /**
     * Return a hash code.
     * @return a hash code for this date
     */
    public int hashCode() {
        int hash = 17;
        hash = 31*hash + month;
        hash = 31*hash + day;
        hash = 31*hash + year;
        return hash;
    }

    /**
     * Unit tests the date data type.
     */
    public static void main(String[] args) {
        Date today = new Date(2, 25, 2004);
        StdOut.println(today);
        for (int i = 0; i < 10; i++) {
            today = today.next();
            StdOut.println(today);
        }

        StdOut.println(today.isAfter(today.next()));
        StdOut.println(today.isAfter(today));
        StdOut.println(today.next().isAfter(today));


        Date birthday = new Date(10, 16, 1971);
        StdOut.println(birthday);
        for (int i = 0; i < 10; i++) {
            birthday = birthday.next();
            StdOut.println(birthday);
        }
    }

}

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值