Java日期和时间


Java提供了java.util包中可用的Date类,该类封装了当前日期和时间。

Date类支持两个构造函数,如下表所示:

构造方法 描述
Date( )

此构造函数使用当前日期和时间初始化对象。

Date(long millisec)

此构造函数接受的参数等于自1970年1月1日午夜以来经过的毫秒数。

以下是Date类的方法:

方法描述
boolean after(Date date)

如果调用Date对象的日期晚于date指定的日期,则返回true;否则,返回false。

boolean before(Date date)

如果调用Date对象的日期早于date指定的日期,则返回true;否则,返回false。

Object clone( )

复制调用日期对象。

int compareTo(Date date)

将调用对象的值与日期进行比较。如果值相等,则返回0。如果调用对象早于日期,则返回负值。如果调用对象晚于日期,则返回正值。

int compareTo(Object obj)

如果obj属于Date类,则其操作与compareTo(Date)相同。否则,它将引发ClassCastException。

boolean equals(Object date)

如果调用Date对象包含的时间和日期与date指定的时间和日期相同,则返回true;否则,返回false。

long getTime( )

返回自1970年1月1日起经过的毫秒数。

int hashCode( )

返回调用对象的哈希码。

void setTime(long time)

设置由时间指定的时间和日期,它表示从1970年1月1日午夜起经过的时间(以毫秒为单位)。

String toString( )

将调用Date对象转换为字符串并返回结果。

获取当前日期和时间


这是Java中获取当前日期和时间的一种非常简单的方法。你可以将简单的Date对象与toString()方法一起使用,以打印当前日期和时间,如下所示:

import java.util.Date;
public class DateDemo {

   public static void main(String args[]) {
      // 实例化一个 Date 对象
      Date date = new Date();

      // 使用 toString() 显示日期和时间
      System.out.println(date.toString());
   }
}

这将产生以下结果:

on May 04 09:51:52 CDT 2009

日期比较


以下是比较两个日期的三种方法:

  • 你可以使用 getTime() 获取两个对象自1970年1月1日午夜以来经过的毫秒数,然后比较这两个值。

  • 你可以使用 before(),after() 和 equals() 方法。例如,因为每月的12号早于18号,所以new Date(99,2,12).before(new Date(99,2,18))返回true。

  • 你可以使用 compareTo() 方法,该方法由Comparable接口定义,并由Date实现。

使用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字母都保留为模式字母,定义如下:

字符描述例子
G时代代号AD
y四位数年份2001
M一年中的月份July or 07
d一个月中的某天10
h在A.M./P.M.的小数(1~12)12
H一天中的小时(0〜23)22
m一小时内的分钟30
s一分钟内的秒数55
S毫秒234
E星期几Tuesday
D一年中的第几天360
F一个月中的星期几2 (second Wed. in July)
w一年中的第几周40
W一个月中的第几周1
aA.M./P.M.标记PM
k一天中的小时(1〜24)24
K小时(AM〜PM)(0〜11)10
z时区Eastern Standard Time
'转义字符Delimiter
''单引号`

使用printf格式化日期


使用 printf 方法可以很容易地完成日期和时间的格式化。你使用两种字母的格式,以t开头,以表的字母之一结尾,如以下代码所示:

import java.util.Date;
public class DateDemo {

   public static void main(String args[]) {
      // 实例化一个 Date 对象
      Date date = new Date();

      // 显示日期和时间
      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[]) {
      // 实例化一个 Date 对象
      Date date = new Date();
  
      // 显示日期和时间
      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[]) {
      // 实例化一个 Date 对象
      Date date = new Date();
  
      // 显示格式化日期
      System.out.printf("%s %tB %<te, %<tY", "Due date:", date);
   }
}

这将产生以下结果:

Due date: February 09, 2004

日期和时间转义字符


CharacterDescriptionExample
c完整的日期和时间Mon May 04 09:51:52 CDT 2009
FISO 8601格式的日期2004-02-09
D美国格式的日期(月/日/年)02/09/2004
T24小时制18:05:19
r12小时制06:05:19 pm
R24小时制,不带秒数18:05
Y四位数年份(有前导零)2004
y年份的最后两位数字(有前导零)04
C年份的前两位数字(有前导零)20
B月份全称February
b缩写的月份名称Feb
m两位数的月份(有前导零)02
d两位数的日期(有前导零)03
e两位数的日期(不带前导零)9
A工作日全称Monday
a缩写的工作日名称
Mon
j一年中的三位数天数(有前导零)069
H两位数的小时数(有前导零),介于00到23之间18
k两位小时(不带前导零),介于0和23之间18
I两位数的小时(前导零),介于01和12之间06
l两位数的小时数(不带前导零),介于1和12之间6
M两位数分钟(有前导零)05
S两位数秒(有前导零)19
L三位数毫秒(有前导零)047
N九位数纳秒(有前导零)047000000
P大写的上午或下午标记PM
p小写的上午或下午标记pm
zRFC 822与GMT的数字偏移量-0800
Z时区PST
s自格林尼治标准时间1970-01-01 00:00:00以来的秒数1078884319
Q自格林尼治标准时间1970-01-01 00:00:00以来的毫秒数1078884319047

还有其他与日期和时间有关的有用的类。有关更多详细信息,你可以参考Java Standard文档。

将字符串解析为日期


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); 
      }
   }
}

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

1818-11-11 Parses as Wed Nov 11 00:00:00 EST 1818

休眠


你可以休眠任何时间,从一毫秒到计算机的整个生命周期内。例如,以下程序将休眠3秒:

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类的具体实现,该类实现你熟悉的普通Gregorian日历。在本教程中我们没有讨论Calendar类,你可以为此查找 Java 标准文档。

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

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

序号构造方法 和 描述
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类提供的一些有用的支持方法的列表:

序号方法 & 描述
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()

重写哈希码。

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;
      // 使用默认的地区和时区用当前的日期和时间初始化一个Gregorian日期
      GregorianCalendar gcalendar = new GregorianCalendar();
      
      // 显示当前的日期和时间信息
      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));

      // 测试当前年份是否为闰年
      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 标准文档。