Java语言-面向对象程序设计-自定义Date类

        在Java中,不建议直接自定义Date类,因为java.util.Date和java.util.Calendar类已经提供了处理日期和时间的基本功能,可以使用SimpleDateFormat类格式化日期(较常用的方式)等。

        这里将自定义封装一个Date类,用于日期对象的创建和格式化,作为一个刚入门的练习案例。

一、创建Date对象

        在src目录中创建工具类包com.project.utils,并在里面新建一个Date对象类文件,代码如下:

package com.project.utils;
import java.util.Calendar;
/*
 * 日期类
 */
public class Date {
    
}

二、定义属性

        在一个日期中,有年、月、日、时、分、秒、周几等相关属性值,这里将它们全部定义为私有的,类的属性定义为私有是面向对象编程中的一个重要实践,它体现了封装性、信息隐藏、控制访问、实现代码模块化和遵循面向对象设计原则等思想和原则。

        代码如下:

package com.project.utils;
import java.util.Calendar;
/*
 * 日期类
 */
public class Date {
    private int year;        // 年
    private int month;       // 月
    private int day;         // 日
    private int hour;        // 小时
    private int minute;      // 分
    private int second;      // 秒
    private char week;       // 周几
    private final String WEEK_STR = "日一二三四五六";
}

        这里定义了一个常量WEEK_STR,是用于将日期中对应星期的数值转换为汉字,索引0为星期日,故“日”要放在第一位。

三、构造函数定义

        此案例中将定义两种构造函数(即构造函数重载):一是无参构造函数,用于创建默认的当前时日期时间(由于java.util.Date中方法已废弃,这里使用java.util.Calendar实例和方法);二是有参构造函数,用于创建指定的日期时间(这里作为案例演示,不过多重载了)。

        Calendar类相关属性和方法,可查看文档了解,地址:Calendar (Java 2 Platform SE 6)

        代码如下:

package com.project.utils;
import java.util.Calendar;
/*
 * 日期类
 */
public class Date {
    private int year;
    private int month;
    private int day;
    private int hour;
    private int minute;
    private int second;
    private char week;
    private final String WEEK_STR = "日一二三四五六";
	
	/**
     * 无参构造函数
     */
    public Date(){
        Calendar date = Calendar.getInstance();
        this.year = date.get(Calendar.YEAR);
        this.month = date.get(Calendar.MONTH);
        this.day = date.get(Calendar.DATE);
        this.hour = date.get(Calendar.HOUR_OF_DAY);
        this.minute = date.get(Calendar.MINUTE);
        this.second = date.get(Calendar.SECOND);
        this.week = WEEK_STR.charAt(date.get(Calendar.DAY_OF_WEEK) - 1);
    }
    /**
     * 有参构造函数
     * @param year
     * @param month
     * @param day
     * @param hour
     * @param minute
     * @param second
     */
    public Date(int year, int month, int day, int hour, int minute, int second){
        this.year = year;
        this.month = month-1;
        this.day = day;
        this.hour = hour;
        this.minute = minute;
        this.second = second;
        // 获取当前是周几
        Calendar date = Calendar.getInstance();
        date.set(year, this.month, this.day, this.hour, this.minute, this.second);
        this.week = WEEK_STR.charAt(date.get(Calendar.DAY_OF_WEEK) - 1);
    }
}

        注意的是,常量WEEK_STR是按照java.util.Date的实例方法getDay()来定义的,索引值是从0到6;但是java.util.Calendar的date.get(Calendar.DAY_OF_WEEK)获取的索引是从1到7,所以需要减1处理。

四、校验参数合法性

        当通过有参构造函数实例对象时,传入的值如果不合法,将会造成程序无法正常运行下,或出现异常等问题。所以将定义一些校验参数合法性的功能函数,在有参构造函数赋值时调用,如果不合法将其设置为0。

        代码如下:

package com.project.utils;
import java.util.Calendar;
/*
 * 日期类
 */
public class Date {
    private int year;
    private int month;
    private int day;
    private int hour;
    private int minute;
    private int second;
    private char week;
    private final String WEEK_STR = "日一二三四五六";
	
	/**
     * 无参构造函数
     */
    public Date(){
        Calendar date = Calendar.getInstance();
        this.year = date.get(Calendar.YEAR);
        this.month = date.get(Calendar.MONTH);
        this.day = date.get(Calendar.DATE);
        this.hour = date.get(Calendar.HOUR_OF_DAY);
        this.minute = date.get(Calendar.MINUTE);
        this.second = date.get(Calendar.SECOND);
        this.week = WEEK_STR.charAt(date.get(Calendar.DAY_OF_WEEK) - 1);
    }
    /**
     * 有参构造函数
     * @param year
     * @param month
     * @param day
     * @param hour
     * @param minute
     * @param second
     */
    public Date(int year, int month, int day, int hour, int minute, int second){
        this.year = year;
        this.month = isMonth(month-1);
        this.day = isDay(day);
        this.hour = isHours(hour);
        this.minute = isMinuteOfSecond(minute);
        this.second = isMinuteOfSecond(second);
        // 获取当前是周几
        Calendar date = Calendar.getInstance();
        date.set(year, this.month, this.day, this.hour, this.minute, this.second);
        this.week = WEEK_STR.charAt(date.get(Calendar.DAY_OF_WEEK) - 1);
    }
    /**
     * 检测月份的合法性
     * @param month
     * @return
     */
    private int isMonth(int month){
        if(month >= 0 && month <= 12) return  month;
        else {
            System.out.println("Invalid month (" + month + ") set to 0.");
            return 0;
        }
    }

    /**
     * 检测日的合法性
     * @param day
     * @return
     */
    private int isDay(int day){
        int monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if(day >= 1 && day <= monthDays[month]) return  day;
        else {
            System.out.println("Invalid day(" + day + ") set to 0.");
            return 0;
        }
    }

    /**
     * 检测小时的合法性
     * @param hour
     * @return
     */
    private int isHours(int hour){
        if(hour >= 0 && hour < 24) return  hour;
        else{
            System.out.println("Invalid hour (" + hour + ") set to 0.");
            return  0;
        }
    }

    /**
     * 检测分钟和秒数的合法性
     * @param value
     * @return
     */
    private int isMinuteOfSecond(int value){
        if(value >= 0 && value < 60) return value;
        else{
            System.out.println("Invalid month (" + value + ") set to 0.");
            return 0;
        }
    }
}

五、格式化日期

        Java中其实已有相关日期格式化类,如java.text.SimpleDateFormat,不过这里我们将通过replaceAll()方法自定义规则,来格式化输出日期。

        代码如下:

package com.project.utils;
import java.util.Calendar;
/*
 * 日期类
 */
public class Date {
    private int year;
    private int month;
    private int day;
    private int hour;
    private int minute;
    private int second;
    private char week;
    private final String WEEK_STR = "日一二三四五六";
	
	/**
     * 无参构造函数
     */
    public Date(){
        Calendar date = Calendar.getInstance();
        this.year = date.get(Calendar.YEAR);
        this.month = date.get(Calendar.MONTH);
        this.day = date.get(Calendar.DATE);
        this.hour = date.get(Calendar.HOUR_OF_DAY);
        this.minute = date.get(Calendar.MINUTE);
        this.second = date.get(Calendar.SECOND);
        this.week = WEEK_STR.charAt(date.get(Calendar.DAY_OF_WEEK) - 1);
    }
    /**
     * 有参构造函数
     * @param year
     * @param month
     * @param day
     * @param hour
     * @param minute
     * @param second
     */
    public Date(int year, int month, int day, int hour, int minute, int second){
        this.year = year;
        this.month = isMonth(month-1);
        this.day = isDay(day);
        this.hour = isHours(hour);
        this.minute = isMinuteOfSecond(minute);
        this.second = isMinuteOfSecond(second);
        // 获取当前是周几
        Calendar date = Calendar.getInstance();
        date.set(year, this.month, this.day, this.hour, this.minute, this.second);
        this.week = WEEK_STR.charAt(date.get(Calendar.DAY_OF_WEEK) - 1);
    }
	/**
     * 输出日期为字符串
     * @param format
     * @return
     */
    public String dateFormatToString(String format){
        format = format.replaceAll("YYYY", "" + year);
        format = format.replaceAll("MM", "" + (month+1));
        format = format.replaceAll("DD", "" + day);
        format = format.replaceAll("hh", "" + hour);
        format = format.replaceAll("ii", "" + minute);
        format = format.replaceAll("ss", "" + second);
        format = format.replaceAll("WW", "" + week);
        return format;
    }
    /**
     * 检测月份的合法性
     * @param month
     * @return
     */
    private int isMonth(int month){
        if(month >= 0 && month <= 12) return  month;
        else {
            System.out.println("Invalid month (" + month + ") set to 0.");
            return 0;
        }
    }

    /**
     * 检测日的合法性
     * @param day
     * @return
     */
    private int isDay(int day){
        int monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if(day >= 1 && day <= monthDays[month]) return  day;
        else {
            System.out.println("Invalid day (" + day + ") set to 0.");
            return 0;
        }
    }

    /**
     * 检测小时的合法性
     * @param hour
     * @return
     */
    private int isHours(int hour){
        if(hour >= 0 && hour < 24) return  hour;
        else{
            System.out.println("Invalid hour (" + hour + ") set to 0.");
            return  0;
        }
    }

    /**
     * 检测分钟和秒数的合法性
     * @param value
     * @return
     */
    private int isMinuteOfSecond(int value){
        if(value >= 0 && value < 60) return value;
        else{
            System.out.println("Invalid minute or second (" + value + ") set to 0.");
            return 0;
        }
    }
}

六、实例

       日期类已经定义好了,现在我们在新建一个java文件,将它引入进来并实例日期对象,输出我们需要的内容。

        代码如下:

package com.project;
import com.project.utils.Date;
/**
 * Test类
 */
public class TestDate {
    public static void main(String[] args) {
        Date date = new Date();
        String dateStr = date.dateFormatToString("YYYY/MM/DD hh:ii:ss 星期WW");
        System.out.println(dateStr);
        System.out.println(date.dateFormatToString("今天是YYYY年MM月DD日 hh时ii分ss秒星期WW"));

        Date date2 = new Date(2024, 5, 26, 10, 44, 30);
        String dateStr2 = date2.dateFormatToString("YYYY/MM/DD hh:ii:ss 星期WW");
        System.out.println(dateStr2);
    }
}

输出结果如下图:

七、优化

        com.project.utils.Date类中的dateFormatToString(String format)方法体写了大量重复性代码,这里将使用HashMap键值对方式存储格式化数据,并通过迭代器循环输出。

        代码如下:

/**
 * 输出日期为字符串
 * @param format
 * @return
 */
public String dateFormatToString(String format){
	Map<String, String>  map = new HashMap<>();
	// 追加对应key和value
	map.put("YYYY", "" + year);
	map.put("MM", ""+(month+1));
	map.put("DD", ""+day);
	map.put("hh", ""+hour);
	map.put("ii", ""+minute);
	map.put("ss", ""+second);
	map.put("WW", ""+week);
	// 循环输出
	for(Map.Entry<String, String> entry: map.entrySet()){
		format = format.replaceAll(entry.getKey(), entry.getValue());
	}
	return format;
}

        此时再次执行运行结果和前面是一样的,如果需要增加规则,直接使用map.put()追加即可(如hour需要输出为24小时,还是12小时,或者小于10的数值是否要在前面补0等)。

八、get和set

        对象的属性通常会被声明为私有(private)的,这是为了封装对象的内部状态,防止外部代码直接访问和修改这些状态,从而确保对象的不变性和安全性。为了实现对私有属性的访问和修改,我们通常会为这些属性提供公共的(public)getter和setter方法。

        此时我们将年、月、日、时、分、秒等私有属性提供公共的setter和getter方法,并对setter的值进行合法性校验。代码如下:

package com.project.utils;
import java.util.Calendar;
import java.util.HashMap
import java.util.Map

/*
 * 日期类
 */
public class Date {
    private int year;
    private int month;
    private int day;
    private int hour;
    private int minute;
    private int second;
    private char week;
    private final String WEEK_STR = "日一二三四五六";
	
	/**
     * 无参构造函数
     */
    public Date(){
        Calendar date = Calendar.getInstance();
        this.year = date.get(Calendar.YEAR);
        this.month = date.get(Calendar.MONTH);
        this.day = date.get(Calendar.DATE);
        this.hour = date.get(Calendar.HOUR_OF_DAY);
        this.minute = date.get(Calendar.MINUTE);
        this.second = date.get(Calendar.SECOND);
        this.week = WEEK_STR.charAt(date.get(Calendar.DAY_OF_WEEK) - 1);
    }
    /**
     * 有参构造函数
     * @param year
     * @param month
     * @param day
     * @param hour
     * @param minute
     * @param second
     */
    public Date(int year, int month, int day, int hour, int minute, int second){
        this.year = year;
        this.month = isMonth(month-1);
        this.day = isDay(day);
        this.hour = isHours(hour);
        this.minute = isMinuteOfSecond(minute);
        this.second = isMinuteOfSecond(second);
        // 获取当前是周几
        Calendar date = Calendar.getInstance();
        date.set(year, this.month, this.day, this.hour, this.minute, this.second);
        this.week = WEEK_STR.charAt(date.get(Calendar.DAY_OF_WEEK) - 1);
    }
	/**
	 * 输出日期为字符串
	 * @param format
	 * @return
	 */
	public String dateFormatToString(String format){
		Map<String, String>  map = new HashMap<>();
		// 追加对应key和value
		map.put("YYYY", "" + year);
		map.put("MM", ""+(month+1));
		map.put("DD", ""+day);
		map.put("hh", ""+hour);
		map.put("ii", ""+minute);
		map.put("ss", ""+second);
		map.put("WW", ""+week);
		// 循环输出
		for(Map.Entry<String, String> entry: map.entrySet()){
			format = format.replaceAll(entry.getKey(), entry.getValue());
		}
		return format;
	}
    /**
     * 检测月份的合法性
     * @param month
     * @return
     */
    private int isMonth(int month){
        if(month >= 0 && month <= 12) return  month;
        else {
            System.out.println("Invalid month (" + month + ") set to 0.");
            return 0;
        }
    }

    /**
     * 检测日的合法性
     * @param day
     * @return
     */
    private int isDay(int day){
        int monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if(day >= 1 && day <= monthDays[month]) return  day;
        else {
            System.out.println("Invalid day (" + day + ") set to 0.");
            return 0;
        }
    }

    /**
     * 检测小时的合法性
     * @param hour
     * @return
     */
    private int isHours(int hour){
        if(hour >= 0 && hour < 24) return  hour;
        else{
            System.out.println("Invalid hour (" + hour + ") set to 0.");
            return  0;
        }
    }

    /**
     * 检测分钟和秒数的合法性
     * @param value
     * @return
     */
    private int isMinuteOfSecond(int value){
        if(value >= 0 && value < 60) return value;
        else{
            System.out.println("Invalid minute of second (" + value + ") set to 0.");
            return 0;
        }
    }
	
	public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = isMonth(month);
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = isDay(day);
    }

    public int getHour() {
        return hour;
    }

    public void setHour(int hour) {
        this.hour = isHours(hour);
    }

    public int getMinute() {
        return minute;
    }

    public void setMinute(int minute) {
        this.minute = isMinuteOfSecond(minute);
    }

    public int getSecond() {
        return second;
    }

    public void setSecond(int second) {
        this.second = isMinuteOfSecond(second);
    }
}

        这里就先讲到这,希望对大家有所帮助!

  • 27
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值