18.JDK7以前的时间类(Date、SimpleDateFormat、Calendar)

JDK7以前的时间类

  • Date类
    • 1. Date概述
    • 2. 常用构造方法
    • 3. 常用方法
    • 4. 代码示例
  • SimpleDateFormat类
    • 1. SimpleDateFormat类概述
    • 2. 构造方法
    • 3. 格式规则
    • 4. 常用方法
    • 5. 综合案例
  • Calendar类
    • 1. Calendar类概述
    • 2. 构造方法
    • 3. 常用方法
    • 4. get方法示例
    • 5. set方法示例
    • 6. add方法示例
    • 7. 综合案例

Date类

1. Date概述

Date类是Java中的一个内置类,用于表示日期和时间。它位于java.util包中。Date类提供了对日期和时间的处理和操作,包括获取当前日期和时间、比较日期和时间、格式化日期和时间等功能。

Date类的实例表示从标准基准时间(称为“纪元”)开始的特定日期和时间。它的精确度可以精确到毫秒级别。Date类提供了一组方法,可以获取和设置日期和时间的各个部分,如年、月、日、小时、分钟和秒等。

需要注意的是,Date类存在一些问题。首先,它在处理日期和时间时是基于计算机的系统时间的,而不是基于时区的。其次,Date类的大部分方法都已被废弃,不再推荐使用。推荐使用java.time包中的新日期和时间API来替代Date类。

2. 常用构造方法

  • public Date():从运行程序的此时此刻到时间原点经历的毫秒值,转换成Date对象,分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒)。

  • public Date(long date):将指定参数的毫秒值date,转换成Date对象,分配Date对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即1970年1月1日00:00:00 GMT)以来的指定毫秒数。

tips: 由于中国处于东八区(GMT+08:00)是比世界协调时间/格林尼治时间(GMT)快8小时的时区,当格林尼治标准时间为0:00时,东八区的标准时间为08:00。

简单来说:使用无参构造,可以自动设置当前系统时间的毫秒时刻;指定long类型的构造参数,可以自定义毫秒时刻。

例如:

import java.util.Date;

public class Demo01Date {
    public static void main(String[] args) {
        // 创建日期对象,把当前的时间
        System.out.println(new Date()); // Tue Jan 16 14:37:35 CST 2020
        // 创建日期对象,把当前的毫秒值转成日期对象
        System.out.println(new Date(0L)); // Thu Jan 01 08:00:00 CST 1970
    }
}

tips:在使用println方法时,会自动调用Date类中的toString方法。Date类对Object类中的toString方法进行了覆盖重写,所以结果为指定格式的字符串。

3. 常用方法

  • public long getTime() 把日期对象转换成对应的时间毫秒值。

  • public void setTime(long time) 把方法参数给定的毫秒值设置给日期对象

示例代码

public class DateDemo02 {
    public static void main(String[] args) {
        //创建日期对象
        Date d = new Date();
        
        //public long getTime():获取的是日期对象从1970年1月1日 00:00:00到现在的毫秒值
        //System.out.println(d.getTime());
        //System.out.println(d.getTime() * 1.0 / 1000 / 60 / 60 / 24 / 365 + "年");

        //public void setTime(long time):设置时间,给的是毫秒值
        //long time = 1000*60*60;
        long time = System.currentTimeMillis();
        d.setTime(time);

        System.out.println(d);
    }
}

4. 代码示例

package text;

import java.util.Date;
import java.util.Random;

/*
需求1:打印时间原点一年后的时间
需求2:随机打印两个任意时间,比较谁的时间在前
 */
public class text84 {
    public static void main(String[] args) {
        //需求1:打印时间原点一年后的时间
        time();
        //需求2:随机打印两个任意时间,比较谁的时间在前
        compare();
    }

    //打印时间原点一年后的时间
    public static void time() {
        //带参构造创建时间对象,获取时间原点的时间
        Date d1 = new Date(0l);
        //获取时间原点时间的毫秒值
        long time = d1.getTime();
        //计算一年后的毫秒值
        time = time + 1000l * 60 * 60 * 24 * 365;
        //带参构造创建时间对象,获取一年后的时间
        Date d2 = new Date(time);
        System.out.println(d2);
    }

    //随机打印两个任意时间,比较谁的时间在前
    public static void compare() {
        //创建随机数,用于表示带参构造中的毫秒数
        Random r = new Random();
        //利用带参构造创建时间对象
        Date d1 = new Date(Math.abs(r.nextInt()));
        Date d2 = new Date(Math.abs(r.nextInt()));
        //获取时间对象的毫秒值
        long time1 = d1.getTime();
        long time2 = d2.getTime();
        //比较两者毫秒值(时间对象不能进行比较)
        if (time1 > time2) {
            System.out.println("第一个时间在后面");
        } else if (time1 < time2) {
            System.out.println("第二个时间在后面");
        } else {
            System.out.println("两者时间一样!");
        }
    }
}

SimpleDateFormat类

1. SimpleDateFormat类概述

SimpleDateFormat类是Java中的一个类,位于java.text包中,用于将日期和时间格式化为指定的字符串,或者将字符串解析为对应的日期和时间。

SimpleDateFormat类提供了一系列模式字符,用于指定日期和时间的格式。这些模式字符可以用于构建日期和时间格式的模式字符串,通过模式字符串,我们可以将日期和时间按照特定的格式输出,或者将特定格式的字符串解析为日期和时间对象。

java.text.SimpleDateFormat 是日期/时间格式化类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来回转换。

  • 格式化:按照指定的格式,把Date对象转换为String对象。

  • 解析:按照指定的格式,把String对象转换为Date对象。

2. 构造方法

由于DateFormat为抽象类,不能直接使用,所以需要常用的子类java.text.SimpleDateFormat。这个类需要一个模式(格式)来指定格式化或解析的标准。构造方法为:

  • public simpleDateFormat() 默认格式

  • public SimpleDateFormat(String pattern):用给定的模式和默认语言环境的日期格式符号构造SimpleDateFormat。参数pattern是一个字符串,代表日期时间的自定义格式。

    细节: 创建对象的格式要跟字符串的格式完全一致

3. 格式规则

常用的格式规则为:

标识字母(区分大小写) 含义
y
M
d
H
m
s

备注:更详细的格式规则,可以参考SimpleDateFormat类的API文档。

4. 常用方法

DateFormat类的常用方法有:

  • public String format(Date date):将Date对象格式化为字符串。

  • public Date parse(String source):将字符串解析为Date对象。

    例如:

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class SimpleDateFormat{
        public static void main(String[] args) throws ParseException {
       
            //1.定义一个字符串表示时间
            String str = "2023-11-11 11:11:11";
            //2.利用空参构造创建simpleDateFormat对象
            // 细节:
            //创建对象的格式要跟字符串的格式完全一致
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = sdf.parse(str);
            //3.打印结果
            System.out.println(date.getTime());//1463494152515
    
    
        }
    
        private static void method1() {
            //1.利用空参构造创建simpleDateFormat对象,默认格式
            SimpleDateFormat sdf1 = new SimpleDateFormat();
            Date d1 = new Date(0L);
            String str1 = sdf1.format(d1);
            System.out.println(str1);//1970/1/1 上午8:00
    
            //2.利用带参构造创建simpleDateFormat对象,指定格式
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
            String str2 = sdf2.format(d1);
            System.out.println(str2);//1970年01月01日 08:00:00
    
         
        }
    }
    
    

5. 综合案例

package text;

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

/*
构造方法:
    public simpleDateFormat() 默认格式
    public simpleDateFormat(String pattern) 指定格式
常见方法:
    public final string format(Date date) 格式化(日期对象 ->字符串)
    public Date parse(string source) 解析(字符串 ->日期对象)
 */
public class text85 {
    public static void main(String[] args) throws ParseException {
        Format();
        Parse();
    }

    //format()方法    public final string format(Date date) 格式化(日期对象 ->字符串)
    public static void Format() {
        //利用空参构造创建对象
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat();
        //创建时间对象
        Date date1 = new Date(0l);
        //调用format()方法
        String str1 = simpleDateFormat1.format(date1);
        System.out.println(str1); //70-1-1 上午8:00

        //利用全参构造创建对象
        SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
        //调用format()方法
        String str2 = simpleDateFormat2.format(date1);
        System.out.println(str2); //1970年01月01日 08:00:00
    }

    //parse()方法    public Date parse(string source) 解析(字符串 ->日期对象)
    public static void Parse() throws ParseException {
        String str1 = "2023-12-23 23:24:00";
        //创建SimpleDateFormat()对象
        //注意:创建对象的格式与字符串的格式一样
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        //调用parse()方法,将str1转换为时间对象
        Date date1 = simpleDateFormat.parse(str1);
        //调用parse()方法,将date1转换为字符串
        String s1 = simpleDateFormat.format(date1);
        System.out.println(s1); //2023-12-23 11:24:00
    }
}

Calendar类

1. Calendar类概述

  • java.util.Calendar类表示一个“日历类”,可以进行日期运算。

Calendar类是Java中的一个抽象类,位于java.util包中,用于处理日期和时间的各个方面,如年、月、日、小时、分钟和秒等。

Calendar类提供了获取和设置日期和时间的各个部分的方法,可以进行日期和时间的计算和操作。它支持各种日历系统,包括常用的公历(Gregorian Calendar)和非常用的日历系统,如农历(Chinese Calendar)等。

Calendar类是作为Date类的替代而引入的,因为Date类在处理日期和时间时存在一些问题。它提供了比Date类更强大和灵活的日期和时间处理功能,并且支持国际化和时区的设置。

细节

  1. Calender是一个抽象类,不能直接new,而是需要通过getInstance()方法创建对象或者直接创建其子类GregorianCalendar对象

  2. Calender.getInstance()会根据系统的不同时区来获取不同的日历对象,默认表示当前时间,并会把时间中的纪元、年、月、日、时、分、秒、星期等等放到一个数组中

  3. 月份:范围0~11.如果获取的是0,实际上是1月,一般在获取的时间后面+1,例如 int month = calendar.get(Calendar.MONTH) + 1;

  4. 星期:1代表星期日,以此类推,7代表星期六

2. 构造方法

Calendar类是一个抽象类,不能创建对象,我们可以使用它的子类:java.util.GregorianCalendar类。

  • 有两种方式可以获取GregorianCalendar对象:
    • 直接创建GregorianCalendar对象;
    • 通过Calendar的静态方法getInstance()方法获取GregorianCalendar对象

3. 常用方法

方法名 说明
public static Calendar getInstance() 获取一个它的子类GregorianCalendar对象。
public int get(int field) 获取某个字段的值。field参数表示获取哪个字段的值,
可以使用Calender中定义的常量来表示:
Calendar.YEAR : 年
Calendar.MONTH :月
Calendar.DAY_OF_MONTH:月中的日期
Calendar.HOUR:小时
Calendar.MINUTE:分钟
Calendar.SECOND:秒
Calendar.DAY_OF_WEEK:星期
public void set(int field,int value) 设置某个字段的值
public void add(int field,int amount) 为某个字段增加/减少指定的值

4. get方法示例

public class Demo {
    public static void main(String[] args) {
        //1.获取一个GregorianCalendar对象
        Calendar instance = Calendar.getInstance();//获取子类对象

        //2.打印子类对象
        System.out.println(instance);

        //3.获取属性
        int year = instance.get(Calendar.YEAR);
        int month = instance.get(Calendar.MONTH) + 1;//Calendar的月份值是0-11
        int day = instance.get(Calendar.DAY_OF_MONTH);

        int hour = instance.get(Calendar.HOUR);
        int minute = instance.get(Calendar.MINUTE);
        int second = instance.get(Calendar.SECOND);

        int week = instance.get(Calendar.DAY_OF_WEEK);//返回值范围:1--7,分别表示:"星期日","星期一","星期二",...,"星期六"

        System.out.println(year + "年" + month + "月" + day + "日" + 
                           	hour + ":" + minute + ":" + second);
        System.out.println(getWeek(week));

    }

    //查表法,查询星期几
    public static String getWeek(int w) {		//w = 1 --- 7
        //做一个表(数组)
        String[] weekArray = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        //            索引      [0]      [1]       [2]      [3]       [4]      [5]      [6]
        return weekArray[w - 1];
    }
}

5. set方法示例

public class Demo {
    public static void main(String[] args) {
        //设置属性——set(int field,int value):
		Calendar c1 = Calendar.getInstance();//获取当前日期

		//计算出生那天是星期几(假如出生日期为:2000年10月1日)
		c1.set(Calendar.YEAR, 2000);
		c1.set(Calendar.MONTH, 10 - 1);//转换为Calendar内部的月份值
		c1.set(Calendar.DAY_OF_MONTH, 1);

		int w = c1.get(Calendar.DAY_OF_WEEK);
		System.out.println("班长出生那天是:" + getWeek(w));

        
    }
    //查表法,查询星期几
    public static String getWeek(int w) {		//w = 1 --- 7
        //做一个表(数组)
        String[] weekArray = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        //            索引      [0]      [1]       [2]      [3]       [4]      [5]      [6]
        return weekArray[w - 1];
    }
}

6. add方法示例

public class Demo {
    public static void main(String[] args) {
        //计算200天以后是哪年哪月哪日,星期几?
		Calendar c2 = Calendar.getInstance();//获取当前日期
        c2.add(Calendar.DAY_OF_MONTH, 200);//日期加200

        int y = c2.get(Calendar.YEAR);
        int m = c2.get(Calendar.MONTH) + 1;//转换为实际的月份
        int d = c2.get(Calendar.DAY_OF_MONTH);

        int wk = c2.get(Calendar.DAY_OF_WEEK);
        System.out.println("200天后是:" + y + "年" + m + "月" + d + "日" + getWeek(wk));

    }
    //查表法,查询星期几
    public static String getWeek(int w) {		//w = 1 --- 7
        //做一个表(数组)
        String[] weekArray = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        //            索引      [0]      [1]       [2]      [3]       [4]      [5]      [6]
        return weekArray[w - 1];
    }
}

7. 综合案例

package text;

import java.util.Calendar;
import java.util.Date;

/*
public static Calendar getInstance()获取一个它的子类GregorianCalendar对象。
public int get(int field)获取某个字段的值。
    field参数表示获取哪个字段的值,可以使用Calender中定义的常量来表示:
    Calendar.YEAR : 年
    Calendar.MONTH :月
    Calendar.DAY_OF_MONTH:月中的日期
    Calendar.HOUR:小时
    Calendar.MINUTE:分钟
    Calendar.SECOND:秒
    Calendar.DAY_OF_WEEK:星期
public void set(int field,int value)设置某个字段的值
public void add(int field,int amount)为某个字段增加/减少指定的值

细节:
    1.Calender是一个抽象类,不能直接new,而是需要通过getInstance()方法创建对象或者直接创建其子类GregorianCalendar对象
    2.Calender.getInstance()会根据系统的不同时区来获取不同的日历对象,默认表示当前时间,并会把时间中的纪元、年、月、日、时、分、秒、星期等等放到一个数组中
    3.月份:范围0~11.如果获取的是0,实际上是1月,一般在获取的时间后面+1,例如 int month = calendar.get(Calendar.MONTH) + 1;
    4.星期:1代表星期日,以此类推,7代表星期六
 */
public class text88 {
    public static void main(String[] args) {
        //创建Calendar日历对象
        //注意:Calendar是个抽象类,不能直接创建对象,需要通过getInstance()方法创建对象或者直接创建其子类GregorianCalendar对象
        Calendar calendar = Calendar.getInstance();

        //获取时间对象
        Date date = calendar.getTime();

        //给日历设置时间对象
        calendar.setTime(date);
        System.out.println(calendar);//java.util.GregorianCalendar[time=1705819185676,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2024,MONTH=0,WEEK_OF_YEAR=4,WEEK_OF_MONTH=4,DAY_OF_MONTH=21,DAY_OF_YEAR=21,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=2,HOUR_OF_DAY=14,MINUTE=39,SECOND=45,MILLISECOND=676,ZONE_OFFSET=28800000,DST_OFFSET=0]


        //获取时间毫秒值
        long time = calendar.getTimeInMillis();
        System.out.println(time);//1705819325203


        //给日历设置时间毫秒值
        calendar.setTimeInMillis(1000);
        System.out.println(calendar);//java.util.GregorianCalendar[time=1000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=1970,MONTH=0,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=1,DAY_OF_YEAR=1,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=8,HOUR_OF_DAY=8,MINUTE=0,SECOND=1,MILLISECOND=0,ZONE_OFFSET=28800000,DST_OFFSET=0]


        //将时间对象改为现在的
        calendar.setTime(date);
        System.out.println(calendar);//java.util.GregorianCalendar[time=1705819655433,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2024,MONTH=0,WEEK_OF_YEAR=4,WEEK_OF_MONTH=4,DAY_OF_MONTH=21,DAY_OF_YEAR=21,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=2,HOUR_OF_DAY=14,MINUTE=47,SECOND=35,MILLISECOND=433,ZONE_OFFSET=28800000,DST_OFFSET=0]


        //获取日历里的某个字段
        int year = calendar.get(Calendar.YEAR);
        //Calender中的month范围是0~11
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(year + ", " + month + "," + day);   //2024, 1,21


        //修改日历中的某个字段
        calendar.set(Calendar.YEAR, 2030);
        calendar.set(Calendar.MONTH, 10);
        calendar.set(Calendar.DAY_OF_MONTH, 21);
        //获取日历里的某个字段
        int year1 = calendar.get(Calendar.YEAR);
        //Calender中的month范围是0~11
        int month1 = calendar.get(Calendar.MONTH) + 1;
        int day1 = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(year1 + ", " + month1 + "," + day1);   //2030, 11,21


        //为某个字段添加/减少指定的值
        calendar.add(Calendar.YEAR, 1);
        int year2 = calendar.get(Calendar.YEAR);
        System.out.println(year2); //2031

    }
}