时间的操作

 

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

1、获取当前时间

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

3、设置时间

4、时间的运算

 

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

 

 

一、获取当前时间

有两种方式可以获得

第一种:使用Date 类。

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

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

Date date = new Date();   (此时的data已经是当前的系统时间了)

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 distanceMin = ca2.get(Calendar.MINUTE) - ca1.get(Calendar.MINUTE);

解释一下上面的代码:

Calendar ca1 = Calendar.getInstance();

得到一个Calendar 对象,Calendar 不提供公用的构造函数,不能new。这行代码得到的新对

象的时间设置为当前时间。

ca1.setTime(date1);

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

ca1.get(Calendar.HOUR_OF_DAY)

获取Calendar 对象的小时值,这里得到的是24 小时制的。这个get 方法参数是int 型的,用

来指定想要获取的域(field),就是什么年啊月啊周啊小时的东西。参数需要用Calendar 类

定义的常量,每个常量对应一个域(field),这些常量的含义都很明显(都可以顾名思义出来),

用的时候在IDE 环境里直接打点选择就可以。

这个get 方法用起来很灵活,比如得到一天的int 值,我们可以得到这一天一个月里的第几天,

也可以得到一周里的第几天,也可以得到一年里的第几天,只要传进对应的参数就OK 了。

有一点需要注意的是,按照我们的习惯,周一是一周的第一天,而老外的习惯是周日才是第一天,

他们是先做完礼拜才开始这一周的。所以如果今天是周一,我们使用

ca1.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 的毫秒值是当前时间的毫秒值,而我们没有进行设置,所以仍然是当前的毫秒值。用那

三行代码,还是用这几行,任君选择。

关于定时任务,似乎跟时间操作的联系并不是很大,但是前面既然提到了定时任

务,索性在这里一起解决了。

设置定时任务很简单,用Timer 类就搞定了。

一、延时执行

首先,我们定义一个类,给它取个名字叫TimeTask,我们的定时任务,就在这个类的main

函数里执行。代码如下:

package test;

import java.util.Timer;

public class TimeTask {

public static void main(String[] args){

Timer timer = new Timer();

timer.schedule(new Task(), 60 * 1000);

}

}

解释一下上面的代码。

上面的代码实现了这样一个功能,当TimeTask 程序启动以后,过一分钟后执行某项任务。很

简单吧:先new 一个Timer 对象,然后调用它的schedule 方法,这个方法有四个重载的方法,

这里我们用其中一个,

public void schedule(TimerTask task,long delay)

首先,第一个参数

第一个参数就是我们要执行的任务。

这是一个TimerTask 对象,确切点说是一个实现TimerTask 的类的对象,因为TimerTask 是

个抽象类。上面的代码里面,Task 就是我们自己定义的实现了TimerTask 的类,因为是在同

一个包里面,所以没有显性的import 进来。Task 类的代码如下

package test;

import java.util.TimerTask;

public class Task extends TimerTask {

public void run(){

System.out.println("定时任务执行");

}

}

我们的Task 必须实现TimerTask 的方法run,要执行的任务就在这个run 方法里面,这里,

我们只让它往控制台打一行字。

第二个参数

第二个参数是一个long 型的值。这是延迟的时间,就是从程序开始以后,再过多少时间来执行

定时任务。这个long 型的值是毫秒数,所以前面我们的程序里面,过一分钟后执行用的参数值

就是 60 * 1000。

二、循环执行

设置定时任务的时候,往往我们需要重复的执行这样任务,每隔一段时间执行一次,而上面的方

法是只执行一次的,这样就用到了schedule 方法的是另一个重载函数

public void schedule(TimerTask task,long delay,long period)

前两个参数就不用说什么了,最后一个参数就是间隔的时间,又是个long 型的毫秒数(看来java

里涉及到时间的,跟这个long 是脱不了干系了),比如我们希望上面的任务从第一次执行后,

每个一分钟执行一次,第三个参数值赋60 * 1000 就ok 了。

三、指定执行时间

既然号称是定时任务,我们肯定希望由我们来指定任务指定的时间,显然上面的方法就不中用了,

因为我们不知道程序什么时间开始运行,就没办法确定需要延时多少。没关系,schedule 四个

重载的方法还没用完呢。用下面这个就OK 了:

public void schedule(TimerTask task,Date time)

比如,我们希望定时任务2006 年7 月2 日0 时0 分执行,只要给第二个参数传一个时间设置

为2006 年7 月2 日0 时0 分的Date 对象就可以了。

有一种情况是,可能我们的程序启动的时候,已经是2006 年7 月3 日了,这样的话,程序一

启动,定时任务就开始执行了。

schedule 最后一个重载的方法是

public void schedule(TimerTask task,Date firstTime,long period)

没必要说什么了吧:)

四、j2ee 中的定时任务

在实际的项目中,往往定时任务需要对web 工程中的资源进行操作,这样一来,用上面的单个

程序的方式可能就有点力不从心了,因为很多web 工程的资源它操作不到。

解决的办法是,使用Servlet,把执行定时任务的那些代码放到Servlet 的init()函数里就可以

了,这个easy,就没有必要再写示例代码了吧(嘿嘿,其实是作者太懒了)。

 

本文为转载,暂不知作者

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值