<时间-2>Date & DateFormat & SimpleDateFormat & Calendar

前面介绍了计算机世界里的一些时间概念,下面着重说明java里最常用的时间类和基本用法。

[b]1.java.util.Date[/b]
此类代表一个精确到[color=red]毫秒[/color]的特定时刻。
在 JDK 1.1 之前,类 Date 有两个额外的功能。它允许把日期解释为年、月、日、小时、分钟和秒值。它也允许格式化和解析日期字符串。不过,这些函数的 API 不易于实现国际化。从 JDK 1.1 开始,应该使用 [b]Calendar [/b]类(后面会介绍)[color=red]实现日期和时间字段之间转换[/color],使用 [b]DateFormat [/b](这是一个抽象类,我们常使用的是SimpleDateFormat)类来[color=red]格式化和解析日期字符串[/color]。Date 中的相应方法已[b]废弃[/b]。

尽管 Date 类打算反映协调世界时 (UTC),但无法做到如此准确,这取决于 Java 虚拟机的主机环境。当前几乎所有操作系统都假定 1 天 = 24 × 60 × 60 = 86400 秒。但对于 UTC,大约每一两年出现一次额外的一秒,[b]称为“闰秒”[/b]。闰秒始终作为当天的最后一秒增加,并且始终在 12 月 31 日或 6 月 30 日增加。例如,1995 年的最后一分钟是 61 秒,因为增加了闰秒。大多数计算机时钟不是特别的准确,因此不能反映闰秒的差别。所以,[color=red][b]Date类实际上表示的GMT时间[/b][/color]。
[b]Date类[color=red]没有[/color]TimeZone时区和Locale区域的设置[/b]。[b]同时对于对日期进行加、减、今天是周几等操作时,一般使推荐用Calendar。[/b]

[b]1.1 Date的构造函数[/b]
常用的两个,
1)Date() //[color=red]返回与地区时区无关的时间,只是toString方法会转换成当前jvm所在机器的本地时间[/color]。
打开源码可以看到:
public Date() {
this(System.currentTimeMillis());
}

获取的是系统当前时间距离1970年1月1日 GMT时间的毫秒数。内部实际调用的是Date(long date)。

2)Date(long date)
查看源码:
public Date(long date) {
fastTime = date;
}

其中fastTime 的定义:private transient long fastTime;
为Date对象指定1970 年 1 月 1 日 00:00:00 GMT以来的毫秒数,据此Date的toString方法可以转换为jvm所在机器的本地时间。

经过上面两个构造函数产生的对象可以调用getTime()方法获取自1970年1月1日以来的GMT时间的毫秒数。[color=red]这个值不会因为时区等外在因素改变,据此可以转换成任意需要的本地时间。[/color]对应,可以为已经构造好的Date对象重新设置时间,调用setTime(long time)。

[b]除此之外指定年月日时分秒等形式的构造函数已经废弃,推荐Calendar或GregorianCalendar相应的构造函数。[/b]

[b]1.2 常用方法[/b]
1)上面说的getTime(),setTime().
2)比较两个日期对象哪个先哪个后,after(Date when),before(Date when),compareTo(Date anotherDate),equals(Object obj),查看内部实现,其实这三个方法都是获取的距GMT时间1970年1月1日的毫秒数然后比较。

再除了clone(),toString(),hashCode()方法,其他方法都已经废弃。

[b]所以,涉及到时间的运算操作,比如加减某个日期,或者单独获取/设置年月日时分秒需要使用替换类Calendar(或GregorianCalendar);如果是Date类型与String转换请使用DateFormat(或SimpleDateFormat)。[/b]

[b]2.java.text.DateFormat/java.text.SimpleDateFormat[/b]

public abstract class DateFormat extends Format
可以看到DateFormat 是日期/时间(日期就是指年月日,时间指时分秒)格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。日期/时间格式化子类(如 SimpleDateFormat)允许进行[color=red]格式化(也就是日期 -> 文本)、解析(文本-> 日期)和标准化[/color]。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 年 1 月 1 日 00:00:00 这一刻开始的毫秒数。

[b]DateFormat是抽象类[/b],所以不能创建对象来使用,直接使用它的静态方法或字段,或通过子类来使用它的可重写方法。

查看源码可看到它提供了几个静态常量,用来表示格式化的时间或日期的格式,有全格式,长,中和短格式,默认“中格式”,表示格式化后日期时间展示出字段的完整性,使用之后才能看到实际效果:
/**
* Constant for full style pattern.
*/
public static final int FULL = 0;
/**
* Constant for long style pattern.
*/
public static final int LONG = 1;
/**
* Constant for medium style pattern.
*/
public static final int MEDIUM = 2;
/**
* Constant for short style pattern.
*/
public static final int SHORT = 3;
/**
* Constant for default style pattern. Its value is MEDIUM.
*/
public static final int DEFAULT = MEDIUM;


[color=red]对应使用这些常量的方式是[/color]public final static DateFormat [b]getDateInstance[/b]()系列方法和public final static DateFormat [b]getTimeInstance[/b]()系列方法和public final static DateFormat [b]getDateTimeInstance[/b]()系列方法。查看源码可以看到,这些获取实例的方法返回的是[b]SimpleDateFormat[/b]实例。通常获取实例后使用format方法来按照格式来格式化日期时间。一般情况DateFormat很少直接使用,而是使用子类SimpleDateFormat。

使用示例:
Date date = new Date();
String s;

s = DateFormat.getDateTimeInstance().format(date);
System.out.println("dateTime:" + s);

/** 输出格式: 2014-1-24 */
s = DateFormat.getDateInstance().format(date);
System.out.println("date:" + s);
s = DateFormat.getTimeInstance().format(date);
System.out.println("time:" + s);

/** 输出格式: 2014-1-24 */
s = DateFormat.getDateInstance(DateFormat.DEFAULT).format(date);
System.out.println("date:" + s);
/** 输出格式: 17:40:54 */
s = DateFormat.getTimeInstance(DateFormat.DEFAULT).format(date);
System.out.println("time:" + s);

/** 输出格式: 2014-1-24 */
s = DateFormat.getDateInstance(DateFormat.MEDIUM).format(date);
System.out.println("date:" + s);
s = DateFormat.getTimeInstance(DateFormat.MEDIUM).format(date);
System.out.println("time:" + s);


/** 输出格式: 2014年1月24日 星期五*/
s = DateFormat.getDateInstance(DateFormat.FULL).format(date);
System.out.println("date:" + s);
s = DateFormat.getTimeInstance(DateFormat.FULL).format(date);
System.out.println("time:" + s);

/** 输出格式: 2014年1月24日*/
s = DateFormat.getDateInstance(DateFormat.LONG).format(date);
System.out.println("date:" + s);
s = DateFormat.getTimeInstance(DateFormat.LONG).format(date);
System.out.println("time:" + s);

/** 输出格式: 14-1-24 */
s = DateFormat.getDateInstance(DateFormat.SHORT).format(date);
System.out.println("date:" + s);
s = DateFormat.getTimeInstance(DateFormat.SHORT).format(date);
System.out.println("time:" + s);

输出结果:
dateTime:2014-1-24 17:40:54
date:2014-1-24
time:17:40:54
date:2014-1-24
time:17:40:54
date:2014-1-24
time:17:40:54
date:2014年1月24日 星期五
time:下午05时40分54秒 CST
date:2014年1月24日
time:下午05时40分54秒
date:14-1-24
time:下午5:40


SimpleDateFormat是DateFormat的子类,可以实例化。SimpleDateFormat 是一个以与语言环境[color=red]有关[/color]的方式来格式化和解析日期的具体类。它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。
public class SimpleDateFormat extends DateFormat

[b]2.1 日期和时间模式[/b]
日期和时间格式由日期和时间模式 字符串指定。在日期和时间模式字符串中,[b]未加引号[/b]的字母 'A' 到 'Z' 和 'a' 到 'z' 被解释为模式字母,用来表示日期或时间字符串元素。[b]文本可以使用单引号 (') 引起来[/b],以免进行解释。"''" 表示单引号。所有其他字符均不解释;只是在格式化时将它们简单复制到输出字符串,或者在解析时与输入字符串进行匹配。
定义了以下模式字母(所有其他字符 'A' 到 'Z' 和 'a' 到 'z' 都被保留):

[img]http://dl2.iteye.com/upload/attachment/0093/6521/97cd0edf-71ca-3a51-b0fb-ef26e7182b18.jpg[/img]

[img]http://dl2.iteye.com/upload/attachment/0093/6523/11c6bb09-aa92-39f6-9bae-684a2f81af45.jpg[/img]

讲到这里,不得不先对[b][color=red]时区TimeZone[/color][/b]和[color=red][b]语言地区Locale[/b][/color]进行说明。
public final class Locale extends Object implements Cloneable, Serializable

Locale 对象表示了特定的地理、政治和文化地区。需要 Locale 来执行其任务的操作称为语言环境敏感的 操作,它使用 Locale 为用户量身定制信息。例如,显示一个数值就是语言环境敏感的操作,应该根据用户的国家、地区或文化的风俗/传统来格式化该数值。

使用此类中的构造方法来创建 Locale:
 Locale(String language)
Locale(String language, String country)
Locale(String language, String country, String variant)


比如:
以下展示每个构造器如何使用:
  //创建一个通用英语的locale.
  Locale locale1 = new Locale("en");
  //创建一个加拿大英语的locale.
  Locale locale2 = new Locale("en", "CA");
  //创建一个美式英语的locale
  //硅谷的英语
  Locale locale3 = new Locale("en", "US", "SiliconValley");


[b]语言参数[/b]是一个有效的 ISO 语言代码。这些代码是由 ISO-639 定义的[b]小写两字母[/b]代码。在许多网站上都可以找到这些代码的完整列表,如:
[url]http://www.loc.gov/standards/iso639-2/englangn.html[/url]
示例:
Language   Code
  =====================
  Arabic    ar
  German    de
  English    en
  Spanish    es
  Japanese   ja
  Hebrew    he
China zh

国家/地区参数是一个有效的 ISO 国家/地区代码。这些代码是由 ISO-3166 定义的大写两字母代码。在许多网站上都可以找到这些代码的完整列表,如:
[url]http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html[/url]
如:
Country   Code
  ======================
  China      CH
  Canada       CA
  France       FR
  Japan       JP
  Germany   DE

[b]预定义的Locale[/b]
  Locale类里有几个Locale类型的静态成员实例.比如 说,Locale.FRANCE 就是预先就准备好的代表法国法语.你可在想要的地方用Locale.FRANCE也可以用new Locale("fr", "FR")的方式来实现.下面给出了一些预定义的现成Locale对象实例
  
  Locale Name           Locale(toString())
  =======================================
  Locale.CHINA           zh_CN
  Locale.CHINESE          zh
  Locale.SIMPLIFIED_CHINESE    zh_CN
  Locale.TRADITIONAL_CHINESE    zh_TW
  Locale.PRC            zh_CN
  Locale.TAIWAN          zh_TW
  Locale.ENGLISH          en
  Locale.UK            en_GB
  Locale.US            en_US
  Locale.FRANCE          fr_FR
  Locale.FRENCH          fr


public abstract class TimeZone extends Object implements Serializable, Cloneable
TimeZone 表示时区偏移量,也可以计算夏令时。

1)通常使用 getDefault 获取 TimeZone,getDefault [color=red]基于程序运行所在的时区[/color]创建 TimeZone。例如,对于在日本运行的程序,getDefault 基于日本标准时间创建 TimeZone 对象。
2)也可以用 getTimeZone 及时区 ID 获取 TimeZone 。例如美国太平洋时区的时区 ID 是 "America/Los_Angeles"。因此,可以使用下面语句获得美国太平洋时间 TimeZone 对象:
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");

可以使用 getAvailableIDs 方法来对所有受支持的时区 ID 进行迭代。可以选择受支持的 ID 来获得 TimeZone。如果想要的时区无法用受支持的 ID 之一表示,那么可以指定自定义时区 ID 来生成 TimeZone。自定义时区 ID 的语法是:
CustomID:
GMT Sign Hours : Minutes
GMT Sign Hours Minutes
GMT Sign Hours
Sign: 下面之一
+ -
Hours:
Digit
Digit Digit
Minutes:
Digit Digit
Digit: 下面之一
0 1 2 3 4 5 6 7 8 9

Hours 必须在 0 至 23 之间,Minutes 必须在 00 至 59 之间。例如,"GMT+10" 和 "GMT+0010" 分别意味着比 GMT 提前 10 小时和 10 分钟。
格式是与区域无关的,并且数字必须取自 Unicode 标准的 Basic Latin 块。没有夏令时转换安排可以用自定义时区 ID 指定。如果指定的字符串与语法不匹配,就使用 "GMT"。
当创建一个 TimeZone 时,指定的自定义时区 ID 采用下面的语法进行标准化:
NormalizedCustomID:
GMT Sign TwoDigitHours : Minutes
Sign: 下面之一
+ -
TwoDigitHours:
Digit Digit
Minutes:
Digit Digit
Digit: 下面之一
0 1 2 3 4 5 6 7 8 9

例如,TimeZone.getTimeZone("GMT-8").getID() 返回 "GMT-08:00"。

[b]三字母时区ID(已废弃)[/b]
为了与 JDK 1.1.x 兼容,一些三字母时区 ID(比如 "PST"、"CTT"、"AST")也受支持。但是,它们的使用[b]被废弃[/b],这是因为相同的缩写经常用于多个时区(例如,"CST" 可以是美国的 "Central Standard Time" 和 "China Standard Time"),但是 Java 平台只可以识别其中一种。
具体可以使用的方法可以查看api文档,比如获取和设置时区,获取默认时区等。

再回到SimpleDateFormat,此类有几个可以选用的构造函数,可以采用默认时区和语言地区,也可以自己指定,可以指定格式化时间的具体格式,格式指定就采用上面提到的日期和时间模式。如果需要中间改变格式,就使用[b]applyPattern[/b]()方法指定新格式就可以了。
常用构造函数如下:
SimpleDateFormat()
用默认的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
SimpleDateFormat(String pattern)
用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。
SimpleDateFormat(String pattern, Locale locale)
用给定的模式和给定语言环境的默认日期格式符号构造 SimpleDateFormat。

举例:
public static void simpleDateFormatTest()
{
Date date = new Date();

// 使用无参构造函数
SimpleDateFormat sdf = new SimpleDateFormat();

// 使用applyPattern改变格式
sdf.applyPattern("yyyy/MM/dd hh:mm:ss");
System.out.println("yyyy/MM/dd hh:mm:ss = " + sdf.format(date));

// 注意跟上面的区别 ,最后有个a,会输出时间是上午还是下午。
sdf.applyPattern("yyyy/MM/dd hh:mm:ss a");
System.out.println("yyyy/MM/dd hh:mm:ss = " + sdf.format(date));

// 注意跟上面的区别,小时用的是大写H,代表24小时制。小写h代表12小时制,所以需要指明上午下午。
sdf.applyPattern("yyyy/MM/dd HH:mm:ss");
System.out.println("yyyy/MM/dd HH:mm:ss = " + sdf.format(date));

// 格式之间可是添加任意自己的说明语言
sdf.applyPattern("今天是yyyy年MM月dd日 HH:mm:ss");
System.out.println("今天是yyyy年MM月dd日 HH:mm:ss = " + sdf.format(date));

// 使用带格式参数的构造函数。注意跟上面的区别,只用一个M和d,这样1月就会展示1月,否则展示01月,但10月仍会展示成10月。d的区别一样。
sdf = new SimpleDateFormat("yyyy/M/d HH:mm:ss");
System.out.println("yyyy/M/d HH:mm:ss = " + sdf.format(date));

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

try
{
// 此时sdf的格式是yyyy/M/d HH:mm:ss,因此可以正确解析“2014/1/12 22:32:34” 或 “2014/01/12 22:32:34”
System.out.println("parse('2014/1/12 22:32:34') = " + sdf.parse("2014/1/12 22:32:34"));
System.out.println("parse('2014/01/12 22:32:34') = " + sdf.parse("2014/01/12 22:32:34"));

// 无法正确解析此格式。
System.out.println("parse('2014-1-12 22:32:34') = " + sdf.parse("2014-1-12 22:32:34"));
}
catch (ParseException e)
{
System.out.println("parse exception" + e);
}
}

输出结果:
yyyy/MM/dd hh:mm:ss = 2014/02/06 09:49:37
yyyy/MM/dd hh:mm:ss = 2014/02/06 09:49:37 下午
yyyy/MM/dd HH:mm:ss = 2014/02/06 21:49:37
今天是yyyy年MM月dd日 HH:mm:ss = 今天是2014年02月06日 21:49:37
yyyy/M/d HH:mm:ss = 2014/2/6 21:49:37
************
parse('2014/1/12 22:32:34') = Sun Jan 12 22:32:34 CST 2014
parse('2014/01/12 22:32:34') = Sun Jan 12 22:32:34 CST 2014
parse exceptionjava.text.ParseException: Unparseable date: "2014-1-12 22:32:34"


[b]2.2 跟时区相关的转换[/b]
SimpleDateFormat可以根据不同时区对同一个Date转换成不同的本地时间。
比如:
		// 按时区进行格式化时间
Date now = new Date();
SimpleDateFormat simpledDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String snow = simpledDF.format(now); // 2014-02-07 10:48:45
System.out.println("snow(gmt+8) = " + snow);

simpledDF.setTimeZone(TimeZone.getTimeZone("GMT+9"));
snow = simpledDF.format(now); // 2014-02-07 11:48:45
System.out.println("snow(gmt+9) = " + snow);
输出:
snow(gmt+8) = 2014-02-07 10:48:45
snow(gmt+9) = 2014-02-07 11:48:45



[b]2.3 DateFormat 和 SimpleDateFormat 类非线程安全[/b]
DateFormat 和 SimpleDateFormat 类不都是线程安全的,在多线程环境下调用 format() 和 parse() 方法应该使用同步代码来避免问题。可以参考:
[url]http://www.cnblogs.com/peida/archive/2013/05/31/3070790.html[/url]

[b]要点总结:[/b]
[color=red]1)频繁创建SimpleDateFormat类会导致性能低下。
2)可使用同步或threadLocal来解决并发问题。[/color]

[b]3.java.util.Calendar[/b]
public abstract class Calendar extends Object
implements Serializable, Cloneable, Comparable<Calendar>

Calendar 类是一个[b]抽象类[/b](跟DateFormat类似),它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,GMT)的偏移量。
该类还为实现包范围外的具体日历系统提供了其他字段和方法。这些字段和方法被定义为 protected。

与其他[b]语言环境敏感类[/b]一样,Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar 的 getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化:
Calendar rightNow = Calendar.getInstance();
因为Calendar是抽象类,此方法返回的实例实际上是它的子类GregorianCalendar的实例。

Calendar 对象能够生成为特定语言和日历风格实现日期-时间格式化所需的所有日历字段值,例如,日语-格里高里历,日语-传统日历。Calendar 定义了某些日历字段返回值的范围,以及这些值的含义。例如,对于所有日历,日历系统第一个月的值是 MONTH == JANUARY。其他值是由具体子类(例如 ERA)定义的。Calendar类与时区或地区相关。有关此内容的细节,请参阅每个字段的文档和子类文档。

[b]字段操作[/b]
可以使用三种方法更改日历字段:set()、add() 和 roll()。

1)set(f, value) 将日历字段 f 更改为 value。此外,它设置了一个内部成员变量,以指示日历字段 f 已经被更改。尽管日历字段 f 是立即更改的,但是直到下次调用 get()、getTime()、getTimeInMillis()、add() 或 roll() 时才会重新计算日历的时间值(以毫秒为单位)。因此,多次调用 set() 不会触发多次不必要的计算。使用 set() 更改日历字段的结果是,其他日历字段也可能发生更改,这取决于日历字段、日历字段值和日历系统。此外,在重新计算日历字段之后,get(f) 没必要通过调用 set 方法返回 value 集合。具体细节是通过具体的日历类确定的。

示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 set(Calendar.MONTH, Calendar.SEPTEMBER) 将该日期设置为 1999 年 9 月 31 日。如果随后调用 getTime(),那么这是解析 1999 年 10 月 1 日的一个暂时内部表示。但是,在调用 getTime() 之前调用 set(Calendar.DAY_OF_MONTH, 30) 会将该日期设置为 1999 年 9 月 30 日,因为在调用 set() 之后没有发生重新计算。

2)add(f, delta) 将 delta 添加到 f 字段中。这等同于调用 set(f, get(f) + delta),但要带以下两个调整:
[b]Add 规则 1[/b]。调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f 中发生的任何溢出为模。溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。
[b]Add 规则 2[/b]。如果期望某一个更小的字段是不变的,但让它等于以前的值是不可能的,因为在字段 f 发生更改之后,或者在出现其他约束之后,比如时区偏移量发生更改,它的最大值和最小值也在发生更改,然后它的值被调整为尽量接近于所期望的值。更小的字段表示一个更小的时间单元。HOUR 是一个比 DAY_OF_MONTH 小的字段。对于不期望是不变字段的更小字段,无需进行任何调整。日历系统会确定期望不变的那些字段。
此外,与 set() 不同,add() 强迫日历系统立即重新计算日历的毫秒数和所有字段。

示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 add(Calendar.MONTH, 13) 将日历设置为 2000 年 9 月 30 日。Add 规则 1 将 MONTH 字段设置为 September,因为向 August 添加 13 个月得出的就是下一年的 September。因为在 GregorianCalendar 中,DAY_OF_MONTH 不可能是 9 月 31 日,所以 add 规则 2 将 DAY_OF_MONTH 设置为 30,即最可能的值。尽管它是一个更小的字段,但不能根据规则 2 调整 DAY_OF_WEEK,因为在 GregorianCalendar 中的月份发生变化时,该值也需要发生变化。

3)roll(f, delta) 将 delta 添加到 f 字段中,但不更改更大的字段。这等同于调用 add(f, delta),但要带以下调整:
[b]Roll 规则[/b]。在完成调用后,更大的字段无变化。更大的字段表示一个更大的时间单元。DAY_OF_MONTH 是一个比 HOUR 大的字段。

示例:请参阅 GregorianCalendar.roll(int, int)。
使用模型。为了帮助理解 add() 和 roll() 的行为,假定有一个用户界面组件,它带有用于月、日、年和底层 GregorianCalendar 的递增或递减按钮。如果从界面上读取的日期为 1999 年 1 月 31 日,并且用户按下月份的递增按钮,那么应该得到什么?如果底层实现使用 set(),那么可以将该日期读为 1999 年 3 月 3 日。更好的结果是 1999 年 2 月 28 日。此外,如果用户再次按下月份的递增按钮,那么该日期应该读为 1999 年 3 月 31 日,而不是 1999 年 3 月 28 日。通过保存原始日期并使用 add() 或 roll(),根据是否会影响更大的字段,用户界面可以像大多数用户所期望的那样运行。

使用示例:
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));    //获取东八区时间
int year = c.get(Calendar.YEAR); //获取年
int month = c.get(Calendar.MONTH) + 1; //获取月份,0表示1月份
int day = c.get(Calendar.DAY_OF_MONTH); //获取当前天数
int first = c.getActualMinimum(c.DAY_OF_MONTH); //获取本月最小天数
int last = c.getActualMaximum(c.DAY_OF_MONTH); //获取本月最大天数
int time = c.get(Calendar.HOUR_OF_DAY); //获取当前小时
int min = c.get(Calendar.MINUTE); //获取当前分钟
int xx = c.get(Calendar.SECOND); //获取当前秒

另外,可以再去参考jdk介绍Calendar的子类GregorianCalendar。

[b]4.总结[/b]
简单总结,主要是明确不同类的使用场景。
Date类就是用来表示与本地地区时区无关的某个确切的时间点,比如对时间进行各种操作之后用来表示一个确切的时间。

DateFormat(SimpleDateFormat)是与时区和地区相关的,可以对时间按指定格式进行format和parse。指定Date,对于不同时区(TimeZone),用DateFormatformat之后的时间是不同的。

Calendar类也是与地区和时区相关的,可以对Date的每个字段(年月日,时分秒)等进行单独的操作,进行时间的增减,比较等运算。

还可以参考:
[url]http://zhujinguo.iteye.com/blog/702013[/url]
[url]http://hi.baidu.com/hqheeonuxybeiuq/item/43ee7645013b38eca4c06636[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值