Date,這個大家都認識了,用于保存日期信息,但不推薦進行日期操作及初始化特定日期
Calendar及其子類GregorianCalendar:日歷類,日期操作,初始化特定日期。
DateFormat及其子類SimpleDateformat: 日期格式化,日期的默認顯示方式不適合中國人,所以需要格式化為中國人常用的格式來顯示。
取得當期日期, Date date=new Date();
初始化特定日期:假設(shè)我們要得到日期為2006-10-27日的對象,需要按如下方式獲得。
Calendar cal = new GregorianCalendar(2006, 9, 27,0,0,0);
Date date = cal.getTime();
注意:date,getTime()取得的是當期時間的毫秒數(shù),月份比實際的減1
GregorianCalendar構(gòu)造方法參數(shù)依次為:年,月-1,日,小時,分,秒
格式化為我們熟悉的方式顯示:
DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH;mm:ss");
String chinesedate = format.format(date);
日期 年,月,日,分,秒的取得
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month=cal.get(Calendar.MONTH)+1;
int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND);
注意:月份,實際的月份要比Clendar得到的加1,因為java月份是從0~11
2.日期基本操作
得到兩個日期相差的天數(shù)
Date endDate=..
Date startDate = ...
相差天數(shù) int days=(int) ((endDate.getTime()-startDate.getTime())/(1000*24*60*60)+0.5);
得到某個月的天數(shù)
Calendar cal = Calendar.getInstance();
int month=cal.getActualMaximum(Calendar.DAY_OF_MONTH);
日期加1天
cal.add(Calendar.DATE, 1);//日期加1天
Calendar.YEAR,Calendar.MONTH,Calendar.WEEK_OF_YEAR),分別是年,月,周
3,java.sql,Date()和java.util.Date();
前面我們說的都是java.util.Date類,java.sql.Date類是操作數(shù)據(jù)庫用的日期類型
java.util.Date date=....
java.sql.Date sqldate=new java.sql.Date(date.getTime());
也可以這樣:String date="2005-11-10";
java.sql.Date sqlDate=java.sql.Date.valueOf(date);
4,定時器
a,編寫類,實現(xiàn)TimeTask接口,定時執(zhí)行的代碼寫入run()方法中
b. timer.schedule(TimeTask子類對象, 開始執(zhí)行的日期, 周期);
周期為毫秒數(shù)
例子:
類MyTask:
import java.util.*;
public class MyTask extends TimerTask {
public void run() {
System.out.println("MyTask 正在執(zhí)行...");
}
}
類TimerDemo:
import java.util.Timer;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Date;
public class TimerDemo {
public static void main(String[] args) {
Timer timer = new Timer();
MyTask task = new MyTask();
Calendar cal = new GregorianCalendar(2006, 9, 28, 12, 49, 0);
Date date = cal.getTime();
System.out.println("date :" + date.toLocaleString());
timer.schedule(task, date, 1000);
}
}
***********************************************************************************************
在某些時候, 我們需要實現(xiàn)這樣的功能,某一程序隔一段時間執(zhí)行一次,而這一事情由系統(tǒng)本身來完成,并不是人為的觸發(fā),我們一般可稱此為定時器任務(wù).
這類技術(shù)主要應(yīng)用到那些需要進行后臺整理數(shù)據(jù)的系統(tǒng)中,比如說數(shù)據(jù)倉儲,數(shù)據(jù)挖掘等.
其實到Java中,實現(xiàn)起來是非常簡單的,下面我們以每隔5秒鐘打引一句"Hello world"為例:
import java.util.TimerTask;
public class TimeTast extends TimerTask ...{
// 在這里寫你要定時執(zhí)行的方法
public void run() ...
System.out.println("Hello World!");
}
}
import java.util.Date;
import java.util.Timer;
/** *//**
* 定時器測試
* @author FeGe
*/
public class Test ...{
public void execute() ...{
Timer timer = new Timer();
TimeTast myTimeTask = new TimeTast();
Date date = new Date();
long timestamp = 5000;
/** *//**
* myTimeTask 指定執(zhí)行的線程 date 指定第一次日期執(zhí)行的時間 timestamp 指定每格多久再次執(zhí)行一次
*/
timer.schedule(myTimeTask, date, timestamp);
}
public static void main(String[] args) ...{
Test t = new Test();
t.execute();
}
}
一個最簡單的定時器任務(wù)就算完成了。是不是太簡單了點呢,其實就這么簡單。
**************************************************************************************************************
下面就Servlet偵聽器結(jié)合Java定時器來講述整個實現(xiàn)過程。要運用Servlet偵聽器需要實現(xiàn) javax.servlet.ServletContextListener接口,同時實現(xiàn)它的contextInitialized (ServletContextEvent event)和contextDestroyed(ServletContextEvent event)兩個接口函數(shù)。考慮定時器有個建立和銷毀的過程,看了前面兩個接口函數(shù),就不容置疑的把建立的過程置入 contextInitialized,把銷毀的過程置入contextDestroyed了。
我把ServletContextListener的實現(xiàn)類取名為ContextListener,在其內(nèi)添加一個定時器,示例代碼如下所示(為考慮篇幅,僅提供部分代碼供讀者參考):
private java.util.Timer timer = null;
public void contextInitialized(ServletContextEvent event) {
timer = new java.util.Timer(true);
event.getServletContext().log("定時器已啟動");
timer.schedule(new MyTask(event.getServletContext()), 0, 60*60*1000);
event.getServletContext().log("已經(jīng)添加任務(wù)調(diào)度表");
}
public void contextDestroyed(ServletContextEvent event) {
timer.cancel();
event.getServletContext().log("定時器銷毀");
}
以 上代碼中, timer.schedule(new MyTask(event.getServletContext()), 0, 60*60*1000)這一行為定時器調(diào)度語句,其中MyTask是自定義需要被調(diào)度的執(zhí)行任務(wù)(在我的財政數(shù)據(jù)中心項目中就是報表計算引擎入口),從 java.util.TimerTask繼承,下面會重點講述,第三個參數(shù)表示每小時(即60*60*1000毫秒)被觸發(fā)一次,中間參數(shù)0表示無延遲。 其它代碼相當簡單,不再詳細說明。
下面介紹MyTask的實現(xiàn),上面的代碼中看到了在構(gòu)造MyTask時,傳入了 javax.servlet.ServletContext類型參數(shù),是為記錄Servlet日志方便而傳入,因此需要重載MyTask的構(gòu)造函數(shù)(其父 類java.util.TimerTask原構(gòu)造函數(shù)是沒有參數(shù)的)。在timer.schedule()的調(diào)度中,設(shè)置了每小時調(diào)度一次,因此如果想實 現(xiàn)調(diào)度任務(wù)每24小時被執(zhí)行一次,還需要判斷一下時鐘點,以常量C_SCHEDULE_HOUR表示(晚上12點,也即0點)。同時為防止24小時執(zhí)行下 來,任務(wù)還未執(zhí)行完(當然,一般任務(wù)是沒有這么長的),避免第二次又被調(diào)度以引起執(zhí)行沖突,設(shè)置了當前是否正在執(zhí)行的狀態(tài)標志isRunning。示例代 碼如下所示:
private static final int C_SCHEDULE_HOUR = 0;
private static boolean isRunning = false;
private ServletContext context = null;
public MyTask(ServletContext context) {
this.context = context;
}
public void run() {
Calendar cal = Calendar.getInstance();
if (!isRunning) {
if (C_SCHEDULE_HOUR == cal.get(Calendar.HOUR_OF_DAY)) {
isRunning = true;
context.log("開始執(zhí)行指定任務(wù)");
//TODO 添加自定義的詳細任務(wù),以下只是示例
int i = 0;
while (i++ < 10) {
context.log("已完成任務(wù)的" + i + "/" + 10);
}
isRunning = false;
context.log("指定任務(wù)執(zhí)行結(jié)束");
}
} else {
context.log("上一次任務(wù)執(zhí)行還未結(jié)束");
}
}
上面代碼中"http://TODO……"之下四行是真正被調(diào)度執(zhí)行的演示代碼(在我的財政數(shù)據(jù)中心項目中就是報表計算過程),您可以換成自己希望執(zhí)行的語句。
到這兒,ServletContextListener和MyTask的代碼都已完整了。最后一步就是把ServletContextListener部署到您的Web工程中去,在您工程的web.xml配置文件中加入如下三行:
<listener>
<listener-class>com.test.ContextListener</listener-class>
</listener>
當然,上面的com.test得換成您自己的包名了。保存web.xml文件后,把工程打包部署到Tomcat中即可。任務(wù)會在每晚12點至凌晨1點之間被執(zhí)行,上面的代碼會在Tomcat的日志文件中記錄如下:
2003-12-05 0:21:39 開始執(zhí)行指定任務(wù)
2003-12-05 0:21:39 已完成任務(wù)的1/10
……
2003-12-05 0:21:39 已完成任務(wù)的10/10
2003-12-05 0:21:39 指定任務(wù)執(zhí)行結(jié)束
posted on 2008-10-26 15:18
Blog of JoJo 閱讀(3426)
評論(7) 編輯 收藏 所屬分類:
Java 相關(guān)