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

news2025/3/17 13:56:31

        在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);
    }
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring框架学习笔记(五):JdbcTemplate 和 声明式事务

基本介绍&#xff1a;通过 Spring 框架可以配置数据源&#xff0c;从而完成对数据表的操作。JdbcTemplate 是 Spring 提供的访问数据库的技术。将 JDBC 的常用操作封装为模板方法 1 JdbcTemplate 使用前需进行如下配置 1.1 在maven项目的pom文件加入以下依赖 <dependencies…

通过Wirtinger流进行相位恢复:理论与算法

文章目录 1. 简介2. 算法描述2.1 初始化(Initialization)2.2 迭代更新(Iterative Updates)2.3 学习率调整&#xff08;Learning Rate Adjustment&#xff09; 3. 代码实现3.1 一维信号测试 &#xff08;Gaussian model&#xff09;3.2 一维信号测试 &#xff08;Coded diffract…

牛皮!亚信安全《2024国家级攻防演练100+必修高危漏洞合集》.pdf

上次分享了2023攻防演练高危漏洞&#xff0c;获得了很多粉丝的好评。 今天再分享一份由亚信安全服务团队结合自身的“外部攻击面管理”服务能力和专业的红队能力&#xff0c;最新发布的《2024攻防演练必修高危漏洞合集》&#xff0c;一共108页&#xff0c;非常详细&#xff0c…

存储+调优:存储-memcached

存储调优&#xff1a;存储-memcached 什么是memcached? 高性能的分布式内存缓存服务器。通过缓存数据库的查询结果&#xff0c;减少数据库访问次数&#xff0c;以提高动态Web应用的速度、提高可扩展性。 在memcached中存什么&#xff1f; 尽快被保存 访问频率高 1.数据保…

X-SCAN:Rust从零实现一个命令行端口扫描工具

0. 成品预览 本文将基于Rust构建一个常见的网络工具&#xff0c;端口扫描器。 按照惯例&#xff0c;还是和之前实现的文本编辑器一样&#xff0c;我给这个工具起名为X-SCAN,它的功能很简单&#xff0c;通过命令行参数的方式对指定IP进行扫描&#xff0c;扫描结束之后返回该IP…

MySQL--数据库--基础知识

目录 1、 数据库作用 2、sql认识 1、DDL 整数类型 浮点 主键 约束: 2、DML 插入数据 修改数据 删除数据 3、DQL-基础查询 字符函数&#xff1a; 逻辑处理&#xff1a; 数学函数&#xff1a; 日期函数&#xff1a; 分组函数&#xff1a; 条件查询: 模糊查询 LIK…

Pycharm在下载安装第三方库时速度慢或超时问题 / 切换国内镜像地址

pycharm下载第三方库速度极慢&#xff0c;搜索了一下&#xff0c;发现方法非常乱&#xff0c;稍作整理。这个问题一般都会出现&#xff0c;在我们开发中遇到的常见问题&#xff0c;根据以下解决方法&#xff0c;基本可以解决&#xff0c;但是不能100%保证 Installing packages …

算法金 | Dask,一个超强的 python 库

本文来源公众号“算法金”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Dask&#xff0c;一个超强的 python 库 1 Dask 概览 在数据科学和大数据处理的领域&#xff0c;高效处理海量数据一直是一项挑战。 为了应对这一挑战&am…

基于open3d加载kitti数据集bin文件

前言 在自动驾驶领域&#xff0c;Kitti数据集是一个非常流行的点云数据集&#xff0c;广泛用于3D目标检测、跟踪和其他相关研究。Open3D是一个强大的开源库&#xff0c;专门用于处理和可视化三维数据。本文将介绍如何使用Open3D来加载和可视化Kitti数据集中的.bin文件。 准备…

【Qt 学习笔记】Qt窗口 | Qt窗口介绍 | QMainwindow类及各组件介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt窗口 | Qt窗口介绍 | QMainwindow类及各组件介绍 文章编号&#xff…

第14章 数据分析案例——2012联邦选举委员会数据库

美国联邦选举委员会发布了有关政治竞选赞助方面的数据。其中包括赞助者的姓名、职业、雇主、地址以及出资额等信息。我们对2012年美国总统大选的数据集比较感兴趣。&#xff08;http://www.fec.gov/disclosurep/PDownload.do&#xff09;。我在2012年6月下载的数据集是一个150M…

【JavaEE进阶】——一万字带你深刻理解Spring IoCDI

目录 &#x1f6a9;Spring是什么 &#x1f388;什么是容器&#xff1f; &#x1f388;什么是 IoC&#xff1f; &#x1f4dd;传统开发思路 &#x1f4dd;IOC思想 &#x1f4dd;IoC 优势 &#x1f388;DI 介绍 &#x1f6a9;IoC 详解 &#x1f388;Bean的存储 &#x…

Python 脚本化 Git 操作:简单、高效、无压力

前言 如何判定此次测试是否达标&#xff0c;代码覆盖率是衡量的标准之一。前段时间&#xff0c;利用fastapi框架重写了覆盖率统计服务&#xff0c;核心其实就是先获取全量代码覆盖率&#xff0c;然后通过diff操作统计增量代码覆盖率&#xff0c;当然要使用diff操作&#xff0c…

力扣HOT100 - 21. 合并两个有序链表

解题思路&#xff1a; class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode dum new ListNode(0), cur dum;while (list1 ! null && list2 ! null) {if (list1.val < list2.val) {cur.next list1;list1 list1.next;} els…

嵌入式之音频基础知识

声音特性 1、响度&#xff1a;人主观上感觉声音的大小&#xff08;俗称音量&#xff09;&#xff0c;由“振幅”和人离声源的距离决定&#xff0c;振幅越大响度越大&#xff0c;人和声源的距离越小&#xff0c;响度越大&#xff1b; 2、音调&#xff1a;声音的高低&#xff0…

Jenkins安装 :Aws EC2下Docker镜像安装

1 安装docker # 安装docker $ sudo yum install -y docker# 启动docker daemon $ sudo systemctl start docker# 用户加入docker组 $ sudo usermod -aG docker username 2 docker安装jenkins $ docker pull jenkins/jenkins:lts# 安装成功 $ docker images REPOSITORY …

vue 表单些某项 v-if 控制后,想在显示时添加验证

效果: 可以为<el-form-item>添加 key 然后prop正常写就行 (key需要唯一值) <el-form-item label"设置" v-if"advanced_setting" key"threshold" prop"threshold"><el-inputv-model"form_Warning.threshold"p…

Python数字比大小获取大的数

目录 一、引言 二、数字比较的基本语法 三、获取较大的数 使用条件语句 使用内置函数 四、处理特殊情况 比较非数字类型 处理无穷大和NaN 五、应用实例 在游戏开发中比较分数 在数据分析中找出最大值 六、优化与性能 七、总结 一、引言 在Python编程的广阔天地中…

通过RAG架构LLM应用程序

在之前的博客文章中&#xff0c;我们已经描述了嵌入是如何工作的&#xff0c;以及RAG技术是什么。本节我们我们将使用 LangChain 库以及 RAG 和嵌入技术在 Python 中构建一个简单的 LLM 应用程序。 我们将使用 LangChain 库在 Python 中构建一个简单的 LLM 应用程序。LangChai…

Python高效数据分析的综合复习指南【时间处理与机器学习】

五、时间处理 一、时间戳-----Timestamp类型 方法1&#xff1a;使用Timestamp创建 pandas.Timestamp(ts_input, freqNone, tzNone, unitNone, yearNone, monthNone, dayNone, hourNone, minuteNone, secondNone, microsecondNone, tzinfoNone, offsetNone) import pandas a…