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 >= 1 && 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[] = { 0, 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 month (" + 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 month (" + 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 >= 1 && 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[] = { 0, 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 month (" + 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 month (" + 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文件,将它引入进来并实例日期对象,输出我们需要的内容。

        代码如下:

package com.project;
import com.project.utils;
/**
 * 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;
/*
 * 日期类
 */
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 >= 1 && 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[] = { 0, 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 month (" + 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 month (" + 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;
        }
    }
	
	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);
    }
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/637211.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java】/*类和对象(上)*/

目录 一、什么是类、什么是对象 二、为什么要学习类和对象 三、初识面向过程和面向对象编程 四、如何定义类 4.1 语法形式 4.2 定义示例 示例一&#xff1a;定义一个描述学生的类 示例二&#xff1a;定义一个描述冰箱的类 示例二&#xff1a;定义一个描述狗的类 4.3…

【HUST】信道编码|基于LDPC码的物理层安全编码方案概述

本文对方案的总结是靠 Kimi 阅读相关论文后生成的&#xff0c;我只看了标题和摘要感觉确实是这么回事&#xff0c;并没有阅读原文。 行文逻辑&#xff1a;是我自己设定的&#xff0c;但我并不是这个研究领域的&#xff0c;所以如果章节划分时有问题&#xff0c;期待指出&#x…

java版Spring Cloud+Mybatis+Oauth2+分布式+微服务+实现工程管理系统

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管…

机器学习补充学习

1、Adaboost算法 Adaboost算法是一种集成学习方法&#xff0c;通过结合多个弱学习器来构建一个强大的预测模型。核心思想&#xff1a;如果一个简单的分类器在训练数据上犯错误&#xff0c;那么它在测试数据上也可能犯错误。 Adaboost通过迭代地训练一系列的分类器&#xff0c…

哪款电脑桌面日历记事本软件好用?推荐优秀的电脑日历记事本

对于众多上班族而言&#xff0c;每天在电脑前忙碌已成为生活常态。若想提升工作效率&#xff0c;简化繁琐的工作流程&#xff0c;选择一款出色的电脑桌面日历与记事本软件就显得至关重要。 然而&#xff0c;在Windows操作系统上设定提醒显得相当繁琐&#xff0c;而系统自带的记…

【Linux】fork和exec中的信号继承探索

fork和exec中的信号继承探索 一、结论二、代码验证2.1 代码编写2.2 代码执行 三、linux源码验证四、APUE中的验证五、其他 一、结论 fork时子进程会继承父进程的信号处理方式&#xff0c;包括父进程设置信号为SIG_DFL或SIG_IGN或捕获后设置自定义处理函数。exce时子进程会继承…

计算机系统的层次结构

操作系统的定义 操作系统&#xff08;Operating System&#xff0c; OS&#xff09;是指控制和管理整个计算机系统的硬件和软件资源&#xff0c;并合理地组织调度计算机的工作和资源的分配&#xff1b;以提供给用户和其他软件方便的接口和环境&#xff1b;它是计算机系统中最基…

【Oracle篇】rman工具实用指南:常用命令详解与实践(第二篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

亚马逊SFP有何优势?跨境卖家又该如何申请?

一、亚马逊SFP概述 亚马逊SFP(Seller Fulfilled Prime)是亚马逊为卖家提供的一项物流计划&#xff0c;旨在让满足条件的卖家能够将其产品纳入Prime服务&#xff0c;获得Prime标识&#xff0c;并直接面向Prime会员市场。通过SFP&#xff0c;卖家可以获得亚马逊的流量倾斜&#…

【低照度图像增强系列(7)】RDDNet算法详解与代码实现(同济大学|ICME)

前言 ☀️ 在低照度场景下进行目标检测任务&#xff0c;常存在图像RGB特征信息少、提取特征困难、目标识别和定位精度低等问题&#xff0c;给检测带来一定的难度。 &#x1f33b;使用图像增强模块对原始图像进行画质提升&#xff0c;恢复各类图像信息&#xff0c;再使用目标检测…

vue项目中如何使用iconfont

导读&#xff1a;vue项目中引入iconfont的方式 iconfont 的三种使用方法 unicode 不常用Font class 像字体一样使用&#xff0c;默认黑色图标&#xff0c;无法修改颜色Symbol 支持多色图标&#xff0c;更灵活&#xff0c;推荐 一、unicode 略 二、Font class 方式一&#…

完美解决原生小程序点击地图markers上的点获取不到对应的坐标信息

需求&#xff1a;地图上有多个markes点&#xff0c;点击每一个获取对应的数据&#xff0c;再根据当前的坐标信息去调用导航。 出现的问题&#xff1a;每次点击的时候获取不到对应的坐标信息&#xff0c;获取到的信息显然不是想要的 原因&#xff1a; 因为你的id不是number类型&…

阿里云手机adb远程连接出现adb问题unauthorized解决

执行adb shell出现下面错误 adb.exe: device unauthorized. This adb servers $ADB_VENDOR_KEYS is not set Try adb kill-server if that seems wrong. Otherwise check for a confirmation dialog on your device.解决&#xff1a;导入和绑定adb的密钥 重启云手机

[Redis]常见数据和内部编码

相关命令 type (key) type 命令实际返回的就是当前键的数据结构类型&#xff0c;它们分别是&#xff1a;string&#xff08;字符串&#xff09;、list&#xff08;列 表&#xff09;、hash&#xff08;哈希&#xff09;、set&#xff08;集合&#xff09;、zset&#xff08;有…

[36#]私有化部署地图套装(全球版)

私有化部署地图套装&#xff08;全球版&#xff09;&#xff0c;是由全球高清卫星影像与100%全球水陆覆盖高程数据组成的全球三维地图套装。 私有化部署地图套装&#xff08;全球版&#xff09; 我们在《难以置信&#xff0c;谁还会用离线地球》一文中&#xff0c;为大家分享…

7 Series FPGAs Integrated Block for PCI Express IP核 Advanced模式配置详解(三)

1 TL Settings Transaction Layer (TL)设置只在Advanced模式下有效。 Endpoint: Unlock and PME_Turn_Off Messages: 与端点的电源管理相关&#xff0c;允许发送解锁和电源管理事件关闭消息。 Root Port: Error Messages: Error Correctable&#xff08;错误可纠正&#xff09…

IO游戏设计思路

1、TCP ,UDP ,KCP ,QUIC TCP 协议最常用的协议 UDP协议非常规的协议&#xff0c;因为需要在线广播&#xff0c;貌似运营商会有一些影响 KCP 基于UDP的协议&#xff0c;GitHub - l42111996/java-Kcp: 基于java的netty实现的可靠udp网络库(kcp算法)&#xff0c;包含fec实现&am…

增强版 Kimi:AI 驱动的智能创作平台,实现一站式内容生成(图片、PPT、PDF)!

前言 基于扣子 Coze 零代码平台&#xff0c;我们从零到一轻松实现了专属 Bot 机器人的搭建。 AI 大模型&#xff08;LLM&#xff09;、智能体&#xff08;Agent&#xff09;、知识库、向量数据库、知识图谱&#xff0c;RAG&#xff0c;AGI 的不同形态愈发显现&#xff0c;如何…

GEO数据挖掘-PCA、差异分析

From 生物技能树 GEO数据挖掘第二节 文章目录 探针注释自主注释流程(了解)PCA图、top1000基因热图探针注释查看示例代码 top 1000 sd 热图离散基因热图&#xff0c;top1000表达基因&#xff0c;只是看一下&#xff0c;不用放文章里 差异分析火山图差异基因热图转换id富集分析-K…

安装mpi4py与dlio_profiler_py的总结

安装mpi4py mpi4py是一个Python库&#xff0c;它提供了与MPI&#xff08;Message Passing Interface&#xff09;兼容的接口&#xff0c;使得Python程序能够利用MPI实现并行计算。mpi4py 的核心是基于MPI标准的C/C实现&#xff0c;它能够在高性能计算环境下进行高效的并行处理…