现在的位置: 首页 > 综合 > 正文

Java日期类型操作

2013年05月21日 ⁄ 综合 ⁄ 共 9892字 ⁄ 字号 评论关闭
在JDK 1.1后,java.util.Date 类型的大多数方法已经不推荐使用了。代替它的是Calendar。 

而在java.sql.Date 和 java.util.Date之间,有些微妙的关系。 

如何将Date类型插入数据库中,成为好多人的一个不小的障碍。 



我们将讨论下面的类: 

1、具体类(和抽象类相对)java.util.Date 
2、抽象类java.text.DateFormat 和它的一个具体子类,java.text.SimpleDateFormat 
3、抽象类java.util.Calendar 和它的一个具体子类,java.util.GregorianCalendar 

具体类可以被实例化, 但是抽象类却不能. 你首先必须实现抽象类的一个具体子类. 

Date 类从Java 开发包(JDK) 1.0 就开始进化, 当时它只包含了几个取得或者设置一个日期数据的各个部分的方法, 
比如说月, 日, 和年. 这些方法现在遭到了批评并且已经被转移到了Calendar类里去了, 
我们将在本文中进一步讨论它. 这种改进旨在更好的处理日期数据的国际化格式. 
就象在JDK 1.1中一样, Date 类实际上只是一个包裹类, 它包含的是一个长整型数据, 
表示的是从GMT(格林尼治标准时间)1970年, 1 月 1日00:00:00这一刻之前或者是之后经历的毫秒数. 


一、创建一个日期对象r 

让我们看一个使用系统的当前日期和时间创建一个日期对象并返回一个长整数的简单例子. 这个时间通常被称为Java 虚拟机(JVM)主机环境的系统时间. 
import java.util.Date;

public class DateExample1 {
	public static void main(String[] args) {
		// Get the system date/time
		Date date = new Date();

		System.out.println(date.getTime());
	}
}


在星期六, 2001年9月29日, 下午大约是6:50的样子, 上面的例子在系统输出设备上显示的结果是 1001803809710. 
在这个例子中,值得注意的是我们使用了Date 构造函数创建一个日期对象, 这个构造函数没有接受任何参数. 
而这个构造函数在内部使用了System.currentTimeMillis() 方法来从系统获取日期. 

那么, 现在我们已经知道了如何获取从1970年1月1日开始经历的毫秒数了. 我们如何才能以一种用户明白的格式来显示这个日期呢? 
在这里类java.text.SimpleDateFormat 和它的抽象基类 java.text.DateFormat 就派得上用场了. 


二、日期数据的定制格式 

假如我们希望定制日期数据的格式, 比方星期六-9月-29日-2001年. 下面的例子展示了如何完成这个工作: 
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateExample2 {

	public static void main(String[] args) {

		SimpleDateFormat bartDateFormat = new SimpleDateFormat("EEEE-MMMM-dd-yyyy");

		Date date = new Date();

		System.out.println(bartDateFormat.format(date));
	}
}


只要通过向SimpleDateFormat 的构造函数传递格式字符串"EEE-MMMM-dd-yyyy", 我们就能够指明自己想要的格式. 
你应该可以看见, 格式字符串中的ASCII 字符告诉格式化函数下面显示日期数据的哪一个部分. 
EEEE是星期, MMMM是月, dd是日, yyyy是年. 字符的个数决定了日期是如何格式化的.传递"EE-MM-dd-yy"会显示 Sat-09-29-01. 
请察看Sun 公司的Web 站点获取日期格式化选项的完整的指示. 


三、将文本数据解析成日期对象r 

假设我们有一个文本字符串包含了一个格式化了的日期对象, 而我们希望解析这个字符串并从文本日期数据创建一个日期对象. 
我们将再次以格式化字符串"MM-dd-yyyy" 调用SimpleDateFormat类, 但是这一次, 我们使用格式化解析而不是生成一个文本日期数据. 
我们的例子, 显示在下面, 将解析文本字符串"9-29-2001"并创建一个值为001736000000 的日期对象. 

例子程序: 

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateExample3 {

	public static void main(String[] args) {
		// Create a date formatter that can parse dates of
		// the form MM-dd-yyyy.
		SimpleDateFormat bartDateFormat = new SimpleDateFormat("MM-dd-yyyy");

		// Create a string containing a text date to be parsed.
		String dateStringToParse = "9-29-2001";

		try {
			// Parse the text version of the date.
			// We have to perform the parse method in a
			// try-catch construct in case dateStringToParse
			// does not contain a date in the format we are expecting.
			Date date = bartDateFormat.parse(dateStringToParse);

			// Now send the parsed date as a long value
			// to the system output.
			System.out.println(date.getTime());
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}
}


五、使用标准的日期格式化过程 

既然我们已经可以生成和解析定制的日期格式了, 让我们来看一看如何使用内建的格式化过程. 
方法 DateFormat.getDateTimeInstance() 让我们得以用几种不同的方法获得标准的日期格式化过程. 
在下面的例子中, 我们获取了四个内建的日期格式化过程. 它们包括一个短的, 中等的, 长的, 和完整的日期格式. 
import java.text.DateFormat;
import java.util.Date;

public class DateExample4 {

	public static void main(String[] args) {
		Date date = new Date();

		DateFormat shortDateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);

		DateFormat mediumDateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);

		DateFormat longDateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);

		DateFormat fullDateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);

		System.out.println(shortDateFormat.format(date));
		System.out.println(mediumDateFormat.format(date));
		System.out.println(longDateFormat.format(date));
		System.out.println(fullDateFormat.format(date));
	}
}


注意我们在对 getDateTimeInstance的每次调用中都传递了两个值. 
第一个参数是日期风格, 而第二个参数是时间风格. 它们都是基本数据类型int(整型). 
考虑到可读性, 我们使用了DateFormat 类提供的常量: SHORT, MEDIUM, LONG, 和 FULL. 
要知道获取时间和日期格式化过程的更多的方法和选项, 请看Sun 公司Web 站点上的解释. 

运行我们的例子程序的时候, 它将向标准输出设备输出下面的内容: 
9/29/01 8:44 PM 
Sep 29, 2001 8:44:45 PM 
September 29, 2001 8:44:45 PM EDT 
Saturday, September 29, 2001 8:44:45 PM EDT 

当然,并不一定要在外部插入时间,因为在数据库中,可以让它自动插入,比如:MSSQL里面,用 

getdate()来插入当前时间,而在Insert时,便可以不用管它了。但有的时候还是避免不了,要手工插入 

时间,以更新数据库。
 

 

下面是一些常用的操作函数:

1.计算某一月份的最大天数 

Calendar time=Calendar.getInstance(); 
time.clear(); 
time.set(Calendar.YEAR,year); //year 为 int 
time.set(Calendar.MONTH,i-1);//注意,Calendar对象默认一月为0           
int day=time.getActualMaximum(Calendar.DAY_OF_MONTH);//本月份的天数 
注:在使用set方法之前,必须先clear一下,否则很多信息会继承自系统当前时间 

2.Calendar和Date的转化 

(1) Calendar转化为Date 
Calendar cal=Calendar.getInstance(); 
Date date=cal.getTime(); 

(2) Date转化为Calendar 
Date date=new Date(); 
Calendar cal=Calendar.getInstance(); 
cal.setTime(date); 

3.格式化输出日期时间 (这个用的比较多) 

Date date=new Date(); 
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 
String time=df.format(date); 
System.out.println(time); 

4.计算一年中的第几星期 

(1)计算某一天是一年中的第几星期 
Calendar cal=Calendar.getInstance(); 
cal.set(Calendar.YEAR, 2006); 
cal.set(Calendar.MONTH, 8); 
cal.set(Calendar.DAY_OF_MONTH, 3); 
int weekno=cal.get(Calendar.WEEK_OF_YEAR); 

(2)计算一年中的第几星期是几号 
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd"); 
Calendar cal=Calendar.getInstance(); 
cal.set(Calendar.YEAR, 2006); 
cal.set(Calendar.WEEK_OF_YEAR, 1); 
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); 
System.out.println(df.format(cal.getTime())); 
输出: 
2006-01-02 

5.add()和roll()的用法(不太常用) 

(1)add()方法 
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd"); 
Calendar cal=Calendar.getInstance(); 
cal.set(Calendar.YEAR, 2006); 
cal.set(Calendar.MONTH, 8); 
cal.set(Calendar.DAY_OF_MONTH, 3); 
cal.add(Calendar.DATE, -4); 
Date date=cal.getTime(); 
System.out.println(df.format(date)); 
cal.add(Calendar.DATE, 4); 
date=cal.getTime(); 
System.out.println(df.format(date)); 
输出: 
    2006-08-30 
    2006-09-03 
(2)roll方法 
cal.set(Calendar.YEAR, 2006); 
cal.set(Calendar.MONTH, 8); 
cal.set(Calendar.DAY_OF_MONTH, 3); 
cal.roll(Calendar.DATE, -4); 
date=cal.getTime(); 
System.out.println(df.format(date)); 
cal.roll(Calendar.DATE, 4); 
date=cal.getTime(); 
System.out.println(df.format(date)); 
输出: 
    2006-09-29 
    2006-09-03 
可见,roll()方法在本月内循环,一般使用add()方法; 

6.计算两个任意时间中间的间隔天数(这个比较常用) 
(1)传进Calendar对象 
    public int getIntervalDays(Calendar startday,Calendar endday)...{       
        if(startday.after(endday))...{ 
            Calendar cal=startday; 
            startday=endday; 
            endday=cal; 
        }    
        long sl=startday.getTimeInMillis(); 
        long el=endday.getTimeInMillis(); 
       
        long ei=el-sl;           
        return (int)(ei/(1000*60*60*24)); 
    } 
(2)传进Date对象 

    public int getIntervalDays(Date startday,Date endday)...{        
        if(startday.after(endday))...{ 
            Date cal=startday; 
            startday=endday; 
            endday=cal; 
        }        
        long sl=startday.getTime(); 
        long el=endday.getTime();       
        long ei=el-sl;           
        return (int)(ei/(1000*60*60*24)); 
    } 
(3)改进精确计算相隔天数的方法 
    public int getDaysBetween (Calendar d1, Calendar d2) ...{ 
        if (d1.after(d2)) ...{ 
            java.util.Calendar swap = d1; 
            d1 = d2; 
            d2 = swap; 
        } 
        int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR); 
        int y2 = d2.get(Calendar.YEAR); 
        if (d1.get(Calendar.YEAR) != y2) ...{ 
            d1 = (Calendar) d1.clone(); 
            do ...{ 
                days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);//得到当年的实际天数 
                d1.add(Calendar.YEAR, 1); 
            } while (d1.get(Calendar.YEAR) != y2); 
        } 
        return days; 
    } 
注意:通过上面的方法可以衍生出求任何时间,如要查出邮箱三周之内收到的邮件(得到当前系统时间-再得到三周前时间)用收件的时间去匹配 
最好装化成 long去比较 
如:1年前日期(注意毫秒的转换) 
   java.util.Date myDate=new java.util.Date(); 
   long myTime=(myDate.getTime()/1000)-60*60*24*365; 
   myDate.setTime(myTime*1000); 
   String mDate=formatter.format(myDate); 

7. String 和 Date ,Long 之间相互转换 (最常用) 

字符串转化成时间类型(字符串可以是任意类型,只要和SimpleDateFormat中的格式一致即可) 
通常我们取时间跨度的时候,会substring出具体时间--long-比较 

java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("M/dd/yyyy hh:mm:ss a",java.util.Locale.US); 
java.util.Date d = sdf.parse("5/13/2003 10:31:37 AM"); 
long dvalue=d.getTime(); 
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
String mDateTime1=formatter.format(d); 

8. 通过时间求时间 

年月周求日期 
SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM F E"); 
java.util.Date date2= formatter2.parse("2003-05 5 星期五"); 
SimpleDateFormat formatter3 = new SimpleDateFormat("yyyy-MM-dd"); 
String mydate2=formatter3.format(date2); 

求是星期几 
mydate= myFormatter.parse("2001-1-1"); 
SimpleDateFormat formatter4 = new SimpleDateFormat("E"); 
String mydate3=formatter4.format(mydate); 

9. java 和 具体的数据库结合 

在开发web应用中,针对不同的数据库日期类型,我们需要在我们的程序中对日期类型做各种不同的转换。
若对应数据库数据是oracle的Date类型,即只需要年月日的,可以选择使用java.sql.Date类型,若对应的是MSsqlserver 数据库的DateTime类型,
即需要年月日时分秒的,选择java.sql.Timestamp类型 
你可以使用dateFormat定义时间日期的格式,转一个字符串即可 


import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

class DateExample5 {

	/**
	 * method 将字符串类型的日期转换为一个timestamp(时间戳记java.sql.Timestamp)
	 * @param dateString 需要转换为timestamp的字符串
	 * @return dataTime timestamp
	 */
	
	public final static java.sql.Timestamp string2Time(String dateString)
			throws java.text.ParseException {
		DateFormat dateFormat;
		dateFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS",Locale.ENGLISH);// 设定格式
		// dateFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss",Locale.ENGLISH);
		dateFormat.setLenient(false);
		java.util.Date timeDate = dateFormat.parse(dateString);// util类型
		java.sql.Timestamp dateTime = new java.sql.Timestamp(timeDate.getTime());
                // Timestamp类型,timeDate.getTime()返回一个long型
		return dateTime;
	}

	
	/**
	 * method 将字符串类型的日期转换为一个Date(java.sql.Date)
	 * @param dateString 需要转换为Date的字符串
	 * @return dataTime Date
	 * @throws java.lang.Exception
	 */

	public final static java.sql.Date string2Date(String dateString)
			throws java.lang.Exception {
		DateFormat dateFormat;
		dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
		dateFormat.setLenient(false);
		java.util.Date timeDate = dateFormat.parse(dateString);// util类型
		java.sql.Date dateTime = new java.sql.Date(timeDate.getTime());// sql类型
		return dateTime;
	}

	
	public static void main(String[] args) {
		Date da = new Date();
		// 注意:这个地方da.getTime()得到的是一个long型的值
		System.out.println(da.getTime());

		// 由日期date转换为timestamp

		// 第一种方法:使用new Timestamp(long)
		Timestamp t = new Timestamp(new Date().getTime());
		System.out.println(t);

		// 第二种方法:使用Timestamp(int year,int month,int date,int hour,int minute,int second,int nano)
		Timestamp tt = new Timestamp(
				Calendar.getInstance().get(Calendar.YEAR) - 1900, 
				Calendar.getInstance().get(Calendar.MONTH), 
				Calendar.getInstance().get(Calendar.DATE),
				Calendar.getInstance().get(Calendar.HOUR),
				Calendar.getInstance().get(Calendar.MINUTE), 
				Calendar.getInstance().get(Calendar.SECOND), 0);
		System.out.println(tt);

		try {
			String sToDate = "2005-8-18";// 用于转换成java.sql.Date的字符串
			String sToTimestamp = "2005-8-18 14:21:12.123";// 用于转换成java.sql.Timestamp的字符串
			Date date1 = string2Date(sToDate);
			Timestamp date2 = string2Time(sToTimestamp);
			System.out.println("Date:" + date1.toString());// 结果显示
			System.out.println("Timestamp:" + date2.toString());// 结果显示
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

【上篇】
【下篇】

抱歉!评论已关闭.