1. Java计算时间依靠1970年1月1日开始的毫秒数.                                                                                                           
*|m~}UxE  2. Date类的构造函数Date()返回代表当前创建的时刻的对象。Date的方法getTime()返回一个long值在数值上等于1970年1月1日之前或之后的时刻。
 -"F'Y5VX  3. DateFormat类用来转换Date到String,反之亦然。静态方法getDateInstance()返回DateFormat的缺省格式;getDateInstance(DateFormat.FIELD)返回指定的DateFormat对象格式。Format(Date d)方法返回String表示日期,例如"January 1,2002."反过来,parse(String s)方法返回以参数字符串表示的Date对象。
 l^H8;ii  4. format()方法返回的字符串格式根据不同地区的时间设置而有所不同。
 NIO1  5. GregorianCalendear类有两个重要的构造函数:GregorianCalerdar(),返回代表当前创建时间的对象;GregorianCalendar(int year,int month,int date)返回代表任意日期的对象。GregorianCalendar类的getTime()方法返回日期对象。Add(int field,int amount)方法通过加或减时间单位,象天数,月数或年数来计算日期。
 KN@p$6'i  GregorianCalendar和 时间
 FM{CvhNP@(  两个GregorianCalendar的构造函数可以用来处理时间。前者创建一个表示日期,小时和分钟的对象:
 $8zWT97Z  XAj@Ek  GregorianCalendar(int year, int month, int date, int hour, int minute)
 aqor3G'  z)$[p|J  第二个创建一个表示一个日期,小时,分钟和秒:
 CTIv!M%_  #i2  GregorianCalendar(int year, int month, int date, int hour, int minute, int second)
 <$b5Yx9  s1nUWk#$z?  首先,我应该提醒一下,每一个构造函数需要时间信息中的日期信息(年,月,日)。如果你想说2:30 p.m.,你必须指出日期。 
qfS]h@]  同样,每一个GregorianCalendar构造函数创建一个在时间上使用毫秒计算的对象。所以,如果你的构造函数只提供年,月,日参数,那小时,分钟,秒和毫秒的值将被置0.
 dh[HJ)2  DateFormat和时间
 "4hCM{E\  你可以使用静态方法getDateTimeInstance(int dateStyle,int timeStyle)来建立DateFormat对象来显示时间和日期。这个方法表明你想要的日期和时间格式。如果你喜欢使用缺省格式,可以使用getDateTimeInstance()来代替它。
 j1,A:heQ )  你可以使用静态方法getTimeInstance(int timeStyle)创建DateFormat对象来显示正确的时间。 
orhaZ8;,(  下面的程序示范了getDateTimeInstance()和getTimeInstance()怎样工作:
 9VY.W}!'p&  `:T@O@==  import java.util.*;
 q<3]c'@  import java.text.*;
 r)EQzF9:  .2XUo14M`  public class Apollo {
 'Q#4JH 2B    public static void main(String[] args) {
 CzmSq68UO      GregorianCalendar liftOffApollo11 = new GregorianCalendar(1969, Calendar.JULY, 16, 9, 32);
 >Nr"$6      Date d = liftOffApollo11.getTime();
 a9gda      DateFormat df1 = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
 :C Zw~{f      DateFormat df2 = DateFormat.getTimeInstance(DateFormat.SHORT);
 OBolVsE8t      String s1 = df1.format(d);
 WK#y{6lWi      String s2 = df2.format(d);
 w[B]MGWF      System.out.println(s1);
 #7s<?6pu      System.out.println(s2);
 -{<[    }
 8 h% 0=O{  } 
' ,(:c      >s!cIWc~  在我的电脑上,上面的程序显示如下:
 R7AL i1Fe  ;ODa+<pl  Jul 16, 1969 9:32:00 AM
 Hc_c];~B  9:32 AM
 &Dq_nOA  (输出根据你所在得地区有所不同) 
@;Yy(Zq  }Fy4l7>F  计算时间间隔
 54Kf7 _mfq    你可能有时需要计算过去的时间;例如,给你开始和结束时间,你想知道制造流程的持续时间。一个出租公司按小时或天数出租东西,计算时间对他们也很有用。同样的,在金融界,经常需要计算重要的支付时间。
 6N>EM"E^!  将问题复杂化,人类至少是用两种方法计算时间。你可以说一天已经结束当24小时过去了,或者日历从今天翻到明天。我们将讨论我们想到的这两种情况。
 GBmA2E?i  时间段,情况 1:严格时间单位
 ? EJ`G  在这种情况中,只有24小时过去,这天才过去,60分钟过去,这个小时才过去,60秒过去,这个分钟才过去,以此类推。在这个方法中,23小时的时间将被认为是0天。
 )KagdlTg  使用这种方法计算时间段,你从计算过去的毫秒开始。为了做到这一点,首先转换每个日期为从1970年1月1日起得毫秒数。你可以从第二个毫秒值中减去第一个毫秒值。这里有一个简单的计算:
 gRAK&J@  926I`EQ|  import java.util.*;
 " M_#7B}  =]5.Q s  public class ElapsedMillis {
 *4md *JIge    public static void main(String[] args) {
 ?y3kMhW#Ov      GregorianCalendar gc1 = new GregorianCalendar(1995, 11, 1, 3, 2, 1);
 #f}wGS8N*      GregorianCalendar gc2 = new GregorianCalendar(1995, 11, 1, 3, 2, 2);
 ;q0g(+^zg`      // the above two dates are one second apart
 `6$Z%      Date d1 = gc1.getTime();
 Y T~LF<T       Date d2 = gc2.getTime();
 jf\8"7k<      long l1 = d1.getTime();
 [IjxQKG+      long l2 = d2.getTime();
 `l(Nc4Ch=      long difference = l2 - l1;
 +DUp0\5s      System.out.println("Elapsed milliseconds: " + difference);
 .$dbqG    }
 :p'$*tM\  }   
hOc{UOIOB  MP&C -R  上面的程序打印如下: 
ABeMEr/3[  e]tnQ5k=bA  Elapsed milliseconds: 1000 
vr3UIfNu  I''MQ tU  这个程序也带来一点混淆。GregorianCalendar类的getTime()返回一个Date对象,Date类的getTime()方法返回从1970年1月1日到这个时间的long类型的毫秒数值。虽然他们的方法名字相同,返回值却不一样!
 xE("l7S  下面的程序片断用简单的整数除法转换毫秒到秒:
 Cf.6b0<o  q x=zV-<  long milliseconds = 1999;
 vxYjh"SK  long seconds = 1999 / 1000;
 +F m+q a  DaILWwq=  这种方法舍去小数部分转换毫秒到秒,所以1,999毫秒等于1秒,2,000毫秒等于2秒。
 X|$9 8,  计算更大的单位-例如天数,小时和分钟-给定一个时间数值,可以使用下面的过程:
 %M&hdRJ  1. 计算最大的单位,减去这个数值的秒数
 \_^ N.v&  2. 计算第二大单位,减去这个数值的秒数
 :K 'cX:;  3. 重复操作直到只剩下秒
 s x q$4  例如,如果你的时间的10,000秒,你想知道这个数值相应的是多少小时,多少分钟,多少秒,你从最大的单位开始:小时。10,000除以3600(一个小时的秒数)得到小时数。使用整数除法,答案是2小时(整数除法中小数舍去)计算剩下的秒数,10,000-(3,600 x 2) = 2,800秒。所以你有2小时和2,800秒。
 Y0-fV7  将2,800秒转换成分钟,2,800除以60。使用整数除法,答案是46。2,800 - (60 x 46) = 40秒。最后答案是2小时,46分,40秒。
 *VoQQT  下面的Java程序使用上面的计算方法:
 RL^ U{CS  u]qn N =I  import java.util.*;
 ?W[(\eZ8`W  >#59=H  public class Elapsed1 {
 F1-)A[z    public void calcHMS(int timeInSeconds) {
 9/(C=&Dsh      int hours, minutes, seconds;
 30|S^`(h      hours = timeInSeconds / 3600;
 Ozq|\ )=      timeInSeconds = timeInSeconds - (hours * 3600);
 pq ?j\l      minutes = timeInSeconds / 60;
 5T"w]0-qC      timeInSeconds = timeInSeconds - (minutes * 60);
 N~[:pY)U      seconds = timeInSeconds;
 BmFm(S=O      System.out.println(hours + " hour(s) " + minutes + " minute(s) " + seconds + " second(s)");
 1}GOs`14    }
 %s76_Zb XN  L~T B|N@}    public static void main(String[] args) {
 hrLmmFfR      Elapsed1 elap = new Elapsed1();
 >[+w&0My-      elap.calcHMS(10000);
 0r502GG    }
 :<hS tl}  } 
}Ad%QWR*  LzllS9is;  输出结果如下:
 l,=REtC2  4/EMUhv]Xa  2 hour(s) 46 minute(s) 40 second(s) 
Foy$#a  fA/`IDG+  上面的程序甚至在时间少于一个小时也可以正确的计算小时数。例如,你用上面的程序计算1,000秒,输出入下: 
eyx~F"u  0 hour(s) 16 minute(s) 40 second(s) 
nZy nanV  举一个现实世界的例子,下面的程序计算阿波罗11飞到月球使用得时间:
 YdXh  Cwte9' G  import java.util.*;
 UU4{|(Hd  4>=0jXA[>  public class LunarLanding {
 s~H| w QB  %=C{Py^HZg    public long getElapsedSeconds(GregorianCalendar gc1, GregorianCalendar gc2) {
 &XqS(B]bW      Date d1 = gc1.getTime();
 *a!M+;`5      Date d2 = gc2.getTime();
 .`:G$y~O      long l1 = d1.getTime();
 %VX^D 87QV      long l2 = d2.getTime();
 /(s a      long difference = Math.abs(l2 - l1);
 {_N5Qu7      return difference / 1000;
 Qt%Kavu    }
 4 NPCeY  D^E7AO{4    public void calcHM(long timeInSeconds) {
 $rt|.`]      long hours, minutes, seconds;
 '4JIcznM      hours = timeInSeconds / 3600;
 xiz6YJ~      timeInSeconds = timeInSeconds - (hours * 3600);
 (ER +_I      minutes = timeInSeconds / 60;
 5Gzowl      System.out.println(hours + " hour(s) " + minutes + " minute(s)" );
 [Ln)iqm9!    }
 !*Lt %  \6' ^iP'    public static void main(String[] args) {
 3H8v9wv}      GregorianCalendar lunarLanding = new GregorianCalendar(1969, Calendar.JULY, 20, 16, 17);
  fbzts W      GregorianCalendar lunarDeparture = new GregorianCalendar(1969, Calendar.JULY, 21, 13, 54);
 \<Wf#y      GregorianCalendar startEVA = new GregorianCalendar(1969, Calendar.JULY, 20, 22, 56);
 6OP!EYd e      GregorianCalendar endEVA = new GregorianCalendar(1969, Calendar.JULY, 21, 1, 9);
 " U5?k-  Uwm+qtJs      LunarLanding apollo = new LunarLanding();
 %Yc"1^. f  KwZ:"=3hk      long eva = apollo.getElapsedSeconds(startEVA, endEVA);
 Tn[K"g      System.out.print("EVA duration = ");
 v[-:kAdR      apollo.calcHM(eva);
 .8Vun N&  c{r~;Q,      long lunarStay = apollo.getElapsedSeconds(lunarLanding, lunarDeparture);
 ly1|/"       System.out.print("Lunar stay = ");
 ^oAzIS/@u      apollo.calcHM(lunarStay);
 PBOP 683    }
 b_?iLPN{  }       
>Uw|EpQjji  S?DzGmxl4  上面程序输出如下:
 8m0g75`  P3Hj8AJ^  EVA duration = 2 hour(s) 13 minute(s)
 dbpv_%;  Lunar stay = 21 hour(s) 37 minute(s) 
HOOGX_yL  8%4,[.  目前为止,我们计算的基础公式是这样的:1分钟=60秒,1小时=60分,1天=24小时。
 @Msz  "1个月=?天,1年=?天"怎么办?
 /KG:29^  月份的天数有28,29,30,31;一年可以是365或366天。因此,当你试图计算严格单位的月份和年时,问题就产生了。例如,如果你使用月份的平均天数(近似30.4375),并且计算下面的时间间隔:
 $}mz|.3bc2  o@0G3Y) M  * July 1, 2:00 a.m. to July 31, 10:00 p.m. 
m'O+@zj`  * February 1, 2:00 a.m. to February 29, 10:00 p.m. 
BPScZ)|!  m VA[n  第一个计算结果是1个月;第二个结果是0个月!
 'TLXdxQNoD  所以,在计算严格单位时间的月份和年份是要想好。
 UUX~p[D+  时间段,情况 2:时间单位变化
 t=G #Fqh  时间单位的变化相当的简单:如果你要统计天数,你可以简单的统计日期变化次数。例如,如果某事15日开始,17日结束,经过2天。(日期先是便到16,再到17)同样的,一个步骤下午3:25开始,4:10 p.m结束,历时1个小时,因为小时数值变了一次(从3到4)。
 ; w 0lE5  图书馆经常使用这种习惯计算时间。例如,如果你从图书馆接一本书,我不能占有这本书最少24小时,会认为图书馆这样才给你算一天。而是,我的账号上记录我借书的日期。日期以变成下一天,我就已经结这本书一天了,即使总计不足24小时。
 I_8,[+ r  当使用单位的变化来计算时间段,通常感觉计算的时间没有多于一个时间单位。例如,如果9:00 p.m.我借了一本图书馆的书,第二天中午还回去,我能算出我借了这本书一天了。可是,有一种感觉在问:"1天和几个小时呢?"这本说总计借出15个小时,答案是一天还差9个小时呢?因此,这篇文章里,我将以一个时间单位变化计算时间。
 {^bitC@vY  单位变化的时间算法
 B -6Uq  这是你怎样计算两个日期的时间变化:
 !C\"A w 6  1. 制作两个日期的拷贝。Close()方法能制作拷贝。 
?5enj)v  2. 使用日期拷贝,将所有的小于时间单位变化的部分设置成它的最小单位。例如,如果计算天数,那么将小时,分钟,秒和毫秒设置成0。这种情况中,使用clear()方法将时间值设置称他们各自的最小值。
 lT6I"J"|Z  3. 取出较早的日期,将你要计算的单位加1,重复直到两个日期相等。你加1的次数就是答案。可以使用before()和after()方法,他们返回boolean值,来判断是否一个日期在另一个日期之前或之后。
 E/cq] U.qz  下面的类的方法用来计算天数和月数。
 BI-T<6w9R  ej}gSe  import java.util.*;
 `UIq&yN<_2  gwQ\- G  public class ElapsedTime {
 yP.SiO-`a  R(:oh(np    public int getDays(GregorianCalendar g1, GregorianCalendar g2) {
 ipjIIF      int elapsed = 0;
 OST1b,      GregorianCalendar gc1, gc2;
 sH8='15   /1&S=MX      if (g2.after(g1)) {
 okEi~2FJ        gc2 = (GregorianCalendar) g2.clone();
 zGtDsR        gc1 = (GregorianCalendar) g1.clone();
 Y e      }
 B:*UE+;L;      else   {
 !w-4rnaqhV        gc2 = (GregorianCalendar) g1.clone();
 ]x!c)`+d         gc1 = (GregorianCalendar) g2.clone();
 7SC8*\yL      }
 aM/RJP  ?=. {;n5      gc1.clear(Calendar.MILLISECOND);
 2 BRMYrk L      gc1.clear(Calendar.SECOND);
 kdFx}@h+k      gc1.clear(Calendar.MINUTE);
 ZUGCS\d2      gc1.clear(Calendar.HOUR_OF_DAY);
 /{AE`7 e  :j5D%cC      gc2.clear(Calendar.MILLISECOND);
 E-b{ {5]G      gc2.clear(Calendar.SECOND);
 O(< ,CG      gc2.clear(Calendar.MINUTE);
 l|t4U "Hx      gc2.clear(Calendar.HOUR_OF_DAY);
 ci+]w(I   ]+3C Wul      while ( gc1.before(gc2) ) {
 m1x9?\=< i        gc1.add(Calendar.DATE, 1);
 wv iO`"L        elapsed++;
 KlE]       }
 %M>,Ptb      return elapsed;
 6kSUlv3vs    }
 x;APoD(H  / 7I1^ZS    public int getMonths(GregorianCalendar g1, GregorianCalendar g2) {
 !)ixm b'?5      int elapsed = 0;
 Bd$ Cu^)X      GregorianCalendar gc1, gc2;
 "rI]$h&,  z6$nGMCc      if (g2.after(g1)) {
 5`uX9]nL%Y        gc2 = (GregorianCalendar) g2.clone();
 Dq'yY8        gc1 = (GregorianCalendar) g1.clone();
 19-Zo@b      }
 6-db<"-      else   {
 VaJ@$2[2        gc2 = (GregorianCalendar) g1.clone();
 ]q8brH        gc1 = (GregorianCalendar) g2.clone();
 _1nh#D <      }
 *dAVu :<  #eYj'nr]_      gc1.clear(Calendar.MILLISECOND);
 a&vO&iwFh      gc1.clear(Calendar.SECOND);
 [&N1+[[      gc1.clear(Calendar.MINUTE);
 L?{?$lm!un      gc1.clear(Calendar.HOUR_OF_DAY);
 ~autqD4uD      gc1.clear(Calendar.DATE);
 S.FmN]fiLx  5~.4Y={`d      gc2.clear(Calendar.MILLISECOND);
 WX){+l6fq      gc2.clear(Calendar.SECOND);
 )6@m6 [U      gc2.clear(Calendar.MINUTE);
 1sF 0h      gc2.clear(Calendar.HOUR_OF_DAY);
 n:C;Dq/      gc2.clear(Calendar.DATE);
 z@Mt~RO/  0uH&#+rKlZ      while ( gc1.before(gc2) ) {
 .E*QNTK.W        gc1.add(Calendar.MONTH, 1);
 []}*v9        elapsed++;
 oM4ga,      }
 c|rCspv      return elapsed;
 q#5w8z    }
 VCu}M+k  }
 _:x8$@{  <n^L<Z+1,#  你可以在上面的类中补充另外的方法来处理小时和分钟。同样,计算时间段的算法能更高效一些,尤其是时间相隔很长。可是,作为介绍目的,这个算法有短小和简单的优势。
 M _i *5  下面的例子使用ElapsedTime类来计算两个日期之间的天使,而后是月数:
 pc4yBME~  i1u#R t)q  import java.util.*;
 b[lh:Ibl  wJPdDtag  public class Example {
 xttJ0="    public static void main(String[] args) {
 qI'v9v_j      GregorianCalendar gc1 = new GregorianCalendar(2001, Calendar.DECEMBER, 30);
 D<bJ8Jv.      GregorianCalendar gc2 = new GregorianCalendar(2002, Calendar.FEBRUARY, 1);
 Y7W@)E)  5,3tv9{W\Q      ElapsedTime et = new ElapsedTime();
 lf8,[>t$      int days = et.getDays(gc1, gc2);
 ~b ;GT p      int months = et.getMonths(gc1, gc2);
 E`UUt+  vRC5`#`T^s      System.out.println("Days = " + days);
 MTUHua{,      System.out.println("Months = " + months);
 NvYqK\AK    }
 H^^AqFD  }
 ?r)S h-3  V3wcBm8x2]  当计算时,上面的程序可能有用,例如,最近的航班。它显示下面的输出: 
R:Fv6 ])r  Q-q<\s.k  Days = 33
 ) THej F  Months = 2 
.~H~4(  HQ]vZ$X$I  (OK,关于航班的计算有些夸张;这个天数算法很适合像图书馆借书这样的应用,你看到了她怎样工作) 
GW5'zD9  告诫
 @VE=7h{  在进行时间工作时要谨慎:你看到的时间段的例子,你精确仔细的考虑非常重要。本文介绍了两种通常计算时间段的想法,但是人们能想到的时间段的计算方法仅仅受到人类想象力的限制。
 1+7_<GXi  所以,当写一个Java程序的时候,确信你的精确度能让使用和以来这些程序的人满意。同样,彻底的测试程序对处理时间的程序非重重要。    
查看本文来源