Code@Oxidy

统计

积分与排名

BookSites

IT NewsSite

IT Websit

Java WebSits

knowledge Library

My Blog

SoftWare

阅读排行榜

java时间操作

java时间操作(转)
2008-03-05 09:19

java 中的时间操作不外乎这四种情况:

1 、获取当前时间

2 、获取某个时间的某种格式

3 、设置时间

4 、时间的运算

好,下面就针对这三种情况,一个一个搞定。

一、获取当前时间

有两种方式可以获得,第一种,使用 Date 类。

j2SE 的包里有两个 Date 类,一个是 java.sql.Date, 一个是 java.util.Date

这里,要使用 java.util.Date 。获取当前时间的代码如下

Date date = new Date();

date.getTime() ;

还有一种方式,使用 System.currentTimeMillis() ;

这两种方式获得的结果是一样的,都是 得到一个当前的时间的long型的时间的毫秒值 ,这个值实际上是当前时间值与 1970 年一月一号零时零分零秒相差的毫秒数。

当前的时间得到了,但实际的应用中最后往往不是要用这个 long 型的东西,用户希望得到的往往是一个时间的字符串,比如" 2006 6 18 号",或" 2006-06-18 ",老外可能希望得到的是" 06-18-2006 ",诸如此类等等。这就是下一个要解决的问题

二、获取某个时间的某种格式

获取时间的格式,需要用到一个专门用于时间格式的类 java.text.SimpleDateFormat

首先,定义一个 SimpleDateFormat 变量

SimpleDateFormat sdf = new SimpleDateFormat("",Locale.SIMPLIFIED_CHINESE);

这个构造函数的定义如下:

SimpleDateFormat(String pattern, Locale locale)

第一个参数 pattern ,我们后面再解释,这里我们使用一个 "", 第二个参数,是用来设置时区的,这里用到了 java.util.Locale 这个类,这个类了面定义了很多静态变量,直接拿过来用就 OK ,我们把时区设置为 Locale.SIMPLIFIED_CHINESE ,只看名字,这个静态变量的意义已经很清楚了。

接下来我们使用这个 SimpleDateFormat 把当前时间格式化为一个如下格式的时间字符串" XXXX XX XX _XX XX XX 秒",代码:

sdf.applyPattern("yyyy年MM月dd日_HH时mm分ss秒");

String timeStr = sdf.format(new Date());

获取时间格式的函数是 format ,这个函数的参数是 java.util.Date 对象,这个没有什么花头。

要说明一下的是这个 pattern ,所谓的模式。这里, yyyy,MM,dd 等,这就是模式。

我们可以在 SimpleDateFormat 的构造函数中指定模式,比如

SimpleDateFormat sdf = new SimpleDateFormat(" yyyy-MM-dd ",Locale.SIMPLIFIED_CHINESE);

也可以获取时间格式的时候使用applyPattern函数临时指定,上面的例子就是这样。

什么字符代表什么,这是 j2se 约定好的,设置模式的时候,我们可以使用约定好的字符加上任何我们想要的字符串。

j2se 对字符所代表的模式的约定列表如下:

Letter Date or Time Component Presentation
G Era designator Text
y Year Year
M Month in year Month
w Week in year Number
W Week in month Number
D Day in year Number
d Day in month Number
F Day of week in month Number
E Day in week Text
a Am/pm marker Text
H Hour in day (0-23) Number
k Hour in day (1-24) Number
K Hour in am/pm (0-11) Number
h Hour in am/pm (1-12) Number
m Minute in hour Number
s Second in minute Number
S Millisecond Number
z Time zone General time zone
Z Time zone RFC 822 time zone

三、设置时间

现实中的时间是由不得我们这些凡夫俗子的,如来老头来了也许还有点可能,但在程序里我们可以变得神通广大。设置时间最典型的应用就是定时任务,我们设置一个时间,到时执行某项任务。

但这里我们主要不是为了解决这个定时任务的问题,我们是为了搞清楚怎么设置时间。关于定时任务,在后面再讨论怎么做。

所谓的设置时间,其实就是我们把一个我们能看懂的时间的显性的值(数字、字符串等),转化成程序能看得懂的( Date 类, long 型的毫秒值等)告诉它。

最直接的思路是, new 一个 Date 类,使用它的某个方法,传进我们指定的数字或字符串类型的值,设置它的时间。

那就先来看一下 Date 这个类,这个类里面有好多方法,什么 setYear setMonth 的,看起来真是太好了,传个 int 值进去就搞定了。

可惜,这些看起来非常 good 的方法从 JDK1.1 以后就不用了,只有一个

setTime (long time)方法还勉强可以用,但是看看这个方法的参数吧, TNND ,是个 long 2006 7 1 号的 long 值是什么?鬼才知道。

所以这个方法不可取,刚才也提到 Date 类里有很多方法从 JDK1.1 以后就不用了,其中就有什么 setYear,setMonth 这样的方法。这些方法不是 JDK 里面没有了,而是被 Calendar 类里面的方法给取代了。(为什么取代?这个问题去问开发 JDK 的那帮人好了)

其实,还是用上面说到的 SimpleDateFormat 就可以搞定,代码,三行:

SimpleDateFormat sdf = new SimpleDateFormat("",Locale.SIMPLIFIED_CHINESE);

sdf. applyPattern("yyyy MM dd _HH mm ss ");

Date date = sdf. parse(" 2006 07 01 _ 14 00 00 ");

一看就懂了吧,第一行是声明对象的,如果前面已经声明了,这一行也省了,第二行是设置模式( pattern )的,关于这个模式,前面已经解释的很详细了,没有什么好说的。第三行,就是要设置的时间跟模式对应的字符串。第三行就返回了我们要得到的 Date 类型。(啰嗦了这么半天,才啰嗦出这么三行代码 :)

Ok ,这个问题搞定,继续下一个。

四、时间的运算

现在我们要开始用 Calendar 了,简单介绍一下先, JDK 的文档里说, Calendar 主要是用来对 Date 对象和 Integer 对象做转换的(这样看起来上面那个问题我们也可以使用 Calendar )。事实上,实际的开发应用中, Calendar 往往用来对时间进行操作,比如说设置个时间啊,对时间进行个对比运算什么滴。

举个例子,已知两个 Date 型时间对象, date1 date2 ,我们需要计算出这两个时间之间相差几个小时,怎么做。

一种思路:得到这两个时间对象的 long 值,然后相减,这就得到了他们相差的毫秒值,然后再根据这个毫秒值算出对应的小时。代码如下:

int distance = (int)((date2.getTime() - date1.getTime())/1000/60/60) ;

简单解释一下 :

date2.getTime() - date1.getTime() 得到相应的 long 型时间值并相减,得到相差的毫秒值,再除 1000 ,得到秒,再除 60 ,得到分,再除 60 ,得到小时。呵呵,我真是够啰嗦!从毫秒转化成秒的时候,我在 google 上搜索了半天才确定一秒等于 1000 毫秒,真是白痴 :)

按上面的方式,似乎问题已经解决了。但是,结果得到的小时值很大可能是个小数,而且,有可能是个小数位很长的小数,这样就要考虑精确位的问题,上面那行代码就不够用了;还有一个比较关键的问题是,根据我们的习惯,往往可能是希望知道他们相差几小时几分几秒,而不是几点几个小时,也可能我们只想知道他们差几个小时,至于小时之外还差几分几秒,我们不感兴趣,这样,上面那行代码也不够用了。

如果要解决这种方式带来的后续的这两个问题,还要写更多的代码,麻烦死了,我是个懒人,不想费那脑子,我需要找一种更直接,更简单的方式来解决。

终于轮到 Calendar 出场了,对上面的问题,解决的代码如下:

Calendar ca1 = Calendar.getInstance();

Calendar ca2 = Calendar.getInstance();

ca1.setTime(date1);

ca2.setTime(date2);

int distanceHour = ca2.get(Calendar.HOUR_OF_DAY) - ca1.get(Calendar.HOUR_OF_DAY);

虽然有五行代码,但这五行代码根本都不用费我的脑子考虑,不像前面的,还要考虑转化什么的,而且这五行代码完全可以像前面一样用一行代码搞定。

这样就得到了这两个时间相差的小时的值,我可以保证绝对是个整数,因为这个distanceHour只是这两个时间对象的小时数之差,而不考虑它们的分秒的差,如果想得它们差几分,代码如下

int distance Min = ca2.get(Calendar.MINUTE) - ca1.get(Calendar.MINUTE);

解释一下上面的代码 :

Calendar ca1 = Calendar.getInstance();

得到一个 Calendar 对象, Calendar 不提供公用的构造函数,不能 new 。这行代码得到的新对象的时间设置为当前时间。

ca1.setTime(date1);

Calendar 对象的时间设置为 date1 的时间。

ca 1 .get(Calendar.HOUR_OF_DAY)

获取 Calendar 对象的小时值,这里得到的是 24 小时制的。这个 get 方法参数是 int 型的,用来指定想要获取的域( field ),就是什么年啊月啊周啊小时的东西。参数需要用 Calendar 类定义的常量,每个常量对应一个域( field ),这些常量的含义都很明显(都可以顾名思义出来),用的时候在 IDE 环境里直接打点选择就可以。

这个 get 方法用起来很灵活,比如得到一天的 int 值,我们可以得到这一天一个月里的第几天,也可以得到一周里的第几天,也可以得到一年里的第几天,只要传进对应的参数就 OK 了。

有一点需要注意的是,按照我们的习惯,周一是一周的第一天,而老外的习惯是周日才是第一天,他们是先做完礼拜才开始这一周的。所以如果今天是周一,我们使用ca 1 .get(Calendar.DAY_OF_WEEK)时得到的值是 2

前面提到, Canlendar 也可以用来设置时间,代码如下

Calendar ca = Calendar.getInstance();

ca.set(Calendar.YEAR, 2006);

ca.set(Calendar.MONTH, 7);

ca.set(Calendar.DAY_OF_MONTH, 1);

ca.set(Calendar.HOUR_OF_DAY, 14);

ca.set(Calendar.MINUTE,0);

ca.set(Calendar.SECOND, 0);

Date date = ca.getTime();

这跟前面第三个问题中的那三行代码的结果基本上是一样的,为什么说基本上?因为毫秒值不一样, ca 的毫秒值是当前时间的毫秒值,而我们没有进行设置,所以仍然是当前的毫秒值。用那三行代码,还是用这几行,任君选择

posted on 2013-06-06 09:49 oxidy 阅读(126) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: