关于对日期和时间进行处理的类

Java自带日期时间类库

日期和时间的处理,在实际开发中十分常见,尽管现在的框架已经十分强大,对时间和日期的处理,正常编程时可能都感觉不到。但是框架使用的也是Java底层的对时间日期处理的类。所以了解学习一下基础,还是十分有必要的。由于日期和时间类使用的十分频繁,Java自身已经有很多类库来处理日期和时间了。

Date类

Date类从jdk1.0时就已经存在了,正是因为它历史悠久,所以这个类里大部分的构造器和方法都已经过时,不推荐使用。
简单介绍一个现在还在用的的构造器以及方法。

//生成一个代表当前日期的Date对象 格式  Sat Jun 06 08:36:05 CST 2020 
        Date date = new Date();
        //返回该时间对应的long型整数。
        long time = date.getTime();
        //根据传入的long型整数生成一个Date对象
        Date date2 = new Date(time);
        //获取当前系统时间.返回值为一个long型整数
        long currentTimeMillis = System.currentTimeMillis();

总体来说,Date这个类设计的有点糟糕,这可不是我说的,是Java官方自己说的。推荐使用Calendar工具类

Calendar类

根据给定的Date对象,Calendar类可以以整数(如:YEAR、MONTH和DATE)的形式检索信息。它是抽象类,因此无法像Date类一样实例化。
Calendar对象提供为特定语言或日历样式实现日期格式化所需的所有时间字段值。


		Calendar c = Calendar.getInstance();
		// 取出年
		System.out.println(c.get(YEAR));
		// 取出月份
		System.out.println(c.get(MONTH));
		// 取出日
		System.out.println(c.get(DATE));
		// 分别设置年、月、日、小时、分钟、秒
		c.set(2003 , 10 , 23 , 12, 32, 23); //2003-11-23 12:32:23
		System.out.println(c.getTime());
		// 将Calendar的年前推1年
		c.add(YEAR , -1); //2002-11-23 12:32:23
		System.out.println(c.getTime());
		// 将Calendar的月前推8个月
		c.roll(MONTH , -8); //2002-03-23 12:32:23
		System.out.println(c.getTime());


		Calendar cal1 = Calendar.getInstance();
		cal1.set(2003, 7, 23, 0, 0 , 0); // 2003-8-23
		cal1.add(MONTH, 6); //2003-8-23 => 2004-2-23
		System.out.println(cal1.getTime());


		Calendar cal2 = Calendar.getInstance();
		cal2.set(2003, 7, 31, 0, 0 , 0); // 2003-8-31
		// 因为进位到后月份改为2月,2月没有31日,自动变成29日
		cal2.add(MONTH, 6); // 2003-8-31 => 2004-2-29
		System.out.println(cal2.getTime());


		Calendar cal3 = Calendar.getInstance();
		cal3.set(2003, 7, 23, 0, 0 , 0); //2003-8-23
		// MONTH字段“进位”,但YEAR字段并不增加
		cal3.roll(MONTH, 6); //2003-8-23 => 2003-2-23
		System.out.println(cal3.getTime());


		Calendar cal4 = Calendar.getInstance();
		cal4.set(2003, 7, 31, 0, 0 , 0); //2003-8-31
		// MONTH字段“进位”后变成2,2月没有31日,
		// YEAR字段不会改变,2003年2月只有28天
		cal4.roll(MONTH, 6); //2003-8-31 => 2003-2-28
		System.out.println(cal4.getTime());

Calendar很强大。

格式化时间日期类

直接输出的Date类往往对国人不是十分友好,我们需要对时间和日期进行格式化,

DateFormat类

11.5.3 DateFormat类

在java.util.Date类中实际上取得的时间是一个非常正确的时间。但是因为其显示的格式不理想,所以无法符合中国人的习惯要求,那么实际上此时就可以为此类进行格式化操作,变为符合于中国人习惯的日期格式。

另外,要提醒读者的是DateFormat类与MessageFormat类都属于Format类的子类,专门用于格式化数据使用。DateFormat类的定义如下:

. public abstract class DateFormat extends Format

从定义上看DateFormat类是一个抽象类,所以肯定无法直接实例化,但是在此抽象类中提供了一个静态方法,可以直接取得本类的实例,个与这个类的常用方法

序 号方 法类 型描 述
1public static final DateFormat
getDateInstance()
普通得到默认的对象
2public static final DateFormat
getDateInstance(int style, Locale aLocale)
普通根据 Locale 得到对象
3public static final DateFormat
getDateTimeInstance()
普通得到日期时间对象
4public static final DateFormat
getDateTimeInstance(int dateStyle,inttimeStyle,Locale aLocale)
普通根据 Locale得到日期时间对象

以上4个方法可以构造DateFormat类的对象,但是发现以上方法中需要传递若干个参数,这些参数表示日期地域或日期的显示形式。下面通过几段代码来了解DateFormat类的操作。

范例:观察DateFormat中的默认操作

package com.datedemo;

import java.util.Calendar;
import java.util.Date;
public class DateTestDemo {
    public static void main(String[] args) {

        DateFormat df1 = null;
        // 声明DateFormat类对象
        DateFormat df2 = null;
        // 声明DateFormat类对象
        df1 = DateFormat.getDateInstance();
        // 取得日期
        df2 = DateFormat.getDateTimeInstance(); // 取得日期时间
        System.out.println("DATE:" + df1.format(new Date()));// 格式化日期
        System.out.println("DATETIME:" + df2.format(new Date()));

    }
}

程序运行结果:

DATE:2008-12-2
DATETIME:2008-12-2 16:25:11

从程序的运行结果中发现,第2个DATETIME显示了时间,但还不是比较合理的中文显示格式。如果想取得更加合理的时间,则必须在构造DateFormat对象时传递若干个参数。

范例:指定显示的风格

  package com.datedemo;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

public class DateTestDemo {
    public static void main(String[] args) {

        DateFormat df1 = null;
        // 声明DateFormat对象
        DateFormat df2 = null;
        // 声明DateFormat对象
        df1 = DateFormat.getDateInstance(DateFormat.YEAR_FIELD, new Locale("zh", "CN"));
        // 取得日期,并设置日期显示风格
        // 取得日期时间,设置日期的显示格式、时间的显示格式
        df2 = DateFormat.getDateTimeInstance(DateFormat.YEAR_FIELD, DateFormat.ERA_FIELD, new Locale("zh", "CN"));
        System.out.println("DATE:" + df1.format(new Date()));
        System.out.println("DATETIME:" + df2.format(new Date()));
    }
}

程序运行结果:

DATE:2008年12月2日
DATETIME:2008年12月2日 下午04时30分29秒 CST

可以发现,以上的日期时间已经被格式化,格式是其默认的时间显示格式,但是如果现在要想得到用户自己需要的日期显示格式,则必须通过DateFormat的子类SimpleDateFormat类完成。

SimpleDateFormat类

在项目开发中,会经常将一个日期格式转换为另外一种日期格式,例如,原日期为2008-10-19 10:11:30.345,转换后日期为2008年10月19日10时11分30秒345毫秒。从这两个日期可以发现,日期的数字完全一样,只是日期格式有所不同,要想实现转换就必须使用java.text包中的SimpleDateFormat类完成。

首先必须先定义出一个完整的日期转化模板,在模板中通过特定的日期标记可以将一个日期格式中的日期数字提取出来,

日期格式化模板标记如下所示

序 号标 记描 述
1y年,年份是 4 位数字,所以需要使用 yyyy 表示
2M年中的月份,月份是两位数字,所以需要使用 MM 表示
3d月中的天数,天数是两位数字,所以需要使用 dd 表示
4H一天中的小时数( 24 小时),小时是两位数字,使用 HH 表示
5m小时中的分钟数,分钟是两位数字,使用 mm 表示
6s分钟中的秒数,秒是两位数字,使用 ss 表示
7S毫秒数,毫秒数是 3位数字,使用 SSS 表示
8y年,年份是 4 位数字,所以需要使用 yyyy 表示

此外,还需要SimpleDateFormat类中的方法才可以完成,SimpleDateFormat类的常用方法如下所示。

SimpleDateFormat类中的常用方法

序号方法类型描述
1public SimpleDateFormat(String pattern)构造通过一个指定的模板构造对象
2public Date parse(String source) throws ParseException普通将一个包含日期的字符串变为 Date 类型
3public final String format(Date date)普通将一个 Date 类型按照指定格式变为 String 类型

范例:格式化日期操作

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

public class DateTestDemo {
    public static void main(String[] args) {
        String strDate = "2008-10-19 10:11:30.345";
        // 定义日期时间的字符串
        // 准备第1个模板,从字符串中提取日期数字
        String pat1 = "yyyy-MM-dd HH:mm:ss.SSS";
        // 准备第2个模板,将提取后的日期数字变为指定的格式
        String pat2 = "yyyy年MM月dd日HH时mm分ss秒SSS毫秒";
        SimpleDateFormat sdf1 = new SimpleDateFormat(pat1);// 实例化模板对象
        SimpleDateFormat sdf2 = new SimpleDateFormat(pat2);// 实例化模板对象
        Date d = null;
        try {
            d = sdf1.parse(strDate);
            // 将给定字符串中的日期提取出来
        } catch (ParseException e) {
            // 如果提供的字符串格式有错误,则进行异常处理
            e.printStackTrace();
        }
        System.out.println(sdf2.format(d));// 将日期变为新的格式 *
    }
}

程序运行结果:

20081019101130345毫秒

以上程序中,首先使用第1个模板将字符串中表示的日期数字取出,然后再使用第2个模板将这些日期数字重新转化为新的格式表示。

SimpleDateFormat类经常用于将String变为Date型数据

在实际的开发中,用户所输入的各个数据都是以String的方式进行接收的,所以此时为了可以正确地将String变为Date型数据,可以依靠SimpleDateFormat类完成。

范例:将String型数据变为Date型数据

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

public class DateTestDemo {
   public static void main(String[] args) throws ParseException {
       // 所有异常 抛出
       String strDate = "2008-10-19 10:11:30.345";
       // 定义日期时间的字符串
       String pat = "yyyy-MM-dd HH:mm:ss.SSS";
       // 定义模板
       SimpleDateFormat sdf = new SimpleDateFormat(pat); // 实例化模板对象
       Date d = sdf.parse(strDate);
       // 将给定字符串中的日期 提取出来
       System.out.println(d);
       // 输出Date对象

   }
}

程序运行结果:

Sun Oct 19 10:11:30 CST 2008

以上程序已经实现了String向Date的转型操作,这样的操作在Java数据库编程时将会经常使用。

实例操作–取得完整日期

实现一:基于Calendar类

以上已经为读者清楚地介绍了如何取得一个系统的日期以及对日期格式的转化操作,但是如果所有的程序都按Calendar程序那样取得日期,则代码肯定会重复很多次,所以可以考虑单独去设计一个类,此类可以取得当前系统的日期时间。但是在使用Calendar类得到时间时有一个问题,例如,现在的月份是9月,正确的日期格式应该是09,但是因为得到日期的方法返回的是int类型,所以最终的返回结果是9,也就是说要想达到正确的显示效果,则必须在9前补一个0。

设计一个取得日期的类,此类可以取得系统的当前时间和时间戳

package com.datedemo;

import java.text.ParseException;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class DateTestDemo {
    public static void main(String[] args) throws ParseException {
        DateTime dt = new DateTime();
        // 实例化DateTime对象
        System.out.println("系统日期:" + dt.getDate());
        System.out.println("中文日期::" + dt.getDateComplete());
        System.out.println("时间戳:" + dt.getTimeStamp());

    }
}

class DateTime {
    private Calendar calendar = null;

    // 定义一个Calendar对象,可以 取得时间
    public DateTime() {
        this.calendar = new GregorianCalendar();// 通过Calendar类的子类实例化
    }

    public String getDate() { // 得到完整的日期,格式为:yyyy-MM-dd HH:mm:ss.SSS
        // 考虑到程序要频繁修改字符串,所以使用StringBuffer提升性能
        StringBuffer buf = new StringBuffer();
        // 依次取得时间
        buf.append(calendar.get(Calendar.YEAR)).append("-");
        buf.append(this.addZero(calendar.get(Calendar.MONTH) + 1, 2));
        buf.append("-");
        buf.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2));
        buf.append(" ");
        buf.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2));
        buf.append(":");
        buf.append(this.addZero(calendar.get(Calendar.MINUTE), 2));
        buf.append(":");
        buf.append(this.addZero(calendar.get(Calendar.SECOND), 2));
        buf.append(".");
        buf.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3));
        return buf.toString();
    }

    // 得到完整的日期,格式为:yyyy年MM月dd日HH时mm分ss秒SSS毫秒
    public String getDateComplete() {
        StringBuffer buf = new StringBuffer();
        buf.append(calendar.get(Calendar.YEAR)).append("年");
        buf.append(this.addZero(calendar.get(Calendar.MONTH) + 1, 2));
        buf.append("月");
        buf.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2));
        buf.append("日 ");
        buf.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2));
        buf.append("时");
        buf.append(this.addZero(calendar.get(Calendar.MINUTE), 2));
        buf.append("分");
        buf.append(this.addZero(calendar.get(Calendar.SECOND), 2));
        buf.append("秒");
        buf.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3));
        buf.append("毫秒");
        return buf.toString();
    }

    // 考虑到日期中有前导0,所以在此处加上了补零的方法
    private String addZero(int num, int len) {
        StringBuffer s = new StringBuffer();
        s.append(num);
        while (s.length() < len) { // 如果长度不足,则继续补0
            s.insert(0, "0"); // 在第1个位置处补0
        }
        return s.toString();
    }

    public String getTimeStamp() { // 得到时间戳:yyyyMMddHHmmssSSS
        StringBuffer buf = new StringBuffer();
        buf.append(calendar.get(Calendar.YEAR));
        buf.append(this.addZero(calendar.get(Calendar.MONTH) + 1, 2));
        buf.append(this.addZero(calendar.get(Calendar.DAY_OF_MONTH), 2));
        buf.append(this.addZero(calendar.get(Calendar.HOUR_OF_DAY), 2));
        buf.append(this.addZero(calendar.get(Calendar.MINUTE), 2));
        buf.append(this.addZero(calendar.get(Calendar.SECOND), 2));
        buf.append(this.addZero(calendar.get(Calendar.MILLISECOND), 3));
        return buf.toString();
    }
};

程序运行结果:

系统日期:2008-10-19 10:42:50.562

中文日期::20081019104250562毫秒

时间戳:20081019104250562

以上程序已经完成了设计的要求,但程序代码太长、太复杂,那么有没有更好的方式呢?实际上是有的,SimpleDateFormat类中可以对一个Date类型进行格式修改的方法,直接使用此方法就可以将一个当前日期的Date类型变为指定的日期格式。

实现二:基于SimpleDateFormat类

使用SimpleDateFormat类可以方便地把一个日期变为指定格式,所以直接使用此类操作是最简单、最合适的。

范例:修改之前的程序

package com.datedemo;

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

public class DateTestDemo {
    public static void main(String[] args) throws ParseException {
        DateTime dt = new DateTime(); // 实例化DateTime对象
        System.out.println("系统日期:" + dt.getDate());
        System.out.println("中文日期::" + dt.getDateComplete());
        System.out.println("时间戳:" + dt.getTimeStamp());

    }
}

class DateTime {
    // 声明日期格式化操作对象,直接对new Date()进行实例化
    private SimpleDateFormat sdf = null;

    // 得到完整的日期,格式为:yyyy-MM-dd HH:mm:ss.SSS
    public String getDate() {
        this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        return this.sdf.format(new Date());
    }

    // 得到完整的日期,格式为:yyyy年MM月dd日HH时mm分ss秒SSS毫秒
    public String getDateComplete() {
        this.sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒SSS毫秒");
        return this.sdf.format(new Date());
    }

    public String getTimeStamp() { // 得到时间戳:yyyyMMddHHmmssSSS
        this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return this.sdf.format(new Date());
    }
};

程序运行结果:

系统日期:2008-10-19 10:47:48.610

中文日期::20081019104748610毫秒

时间戳:20081019104748610

第二种代码显而易见的简洁,推荐使用实现二这种方法。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值