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 |
a | A.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
日期和时间转义字符
Character | Description | Example |
---|---|---|
c | 完整的日期和时间 | Mon May 04 09:51:52 CDT 2009 |
F | ISO 8601格式的日期 | 2004-02-09 |
D | 美国格式的日期(月/日/年) | 02/09/2004 |
T | 24小时制 | 18:05:19 |
r | 12小时制 | 06:05:19 pm |
R | 24小时制,不带秒数 | 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 |
z | RFC 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 标准文档。