日期日历和异常类

日期日历和异常类

1 日期日历类

1.1 日期和格式化类

public static void main(String[] args) throws ParseException {
        // 日期格式化
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        // 把日期转换成字符串
        String format = simpleDateFormat.format(new Date());
        System.out.println(format);

        Date parse = simpleDateFormat.parse("2021年01月01日 12:12:12");
        System.out.println(parse);
    }

    private static void demo1() {
        // 北京时间距离世界时间相差8小时
        Date date = new Date();
        // 获取日期距离计算机元年的毫秒值
        System.out.println(date.getTime());
        System.out.println(date);

        // 距离计算机元年过去参数毫秒的时间
        Date date1 = new Date(1000L);
        System.out.println(date1);
    }

1.2 日历类

package cn.javasm.demo;

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

/**
 * @className: TestDemo3
 * @description:
 * @author: gfs
 * @date: 2025/7/4 10:56
 * @version: 0.1
 * @since: jdk17
 */
public class TestDemo3 {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        // 设置日历时间
//        calendar.set(2020,1,1,10,20,58);
        calendar.setTime(new Date());
        System.out.println(calendar);
        // 年
        int year = calendar.get(Calendar.YEAR);
        System.out.println(year);
        // 月
        int month = calendar.get(Calendar.MONTH);
        System.out.println(month + 1);
        // 日
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(day);
        // 时
        int hour = calendar.get(Calendar.HOUR);
        System.out.println(hour);
        // 分
        int minute = calendar.get(Calendar.MINUTE);
        System.out.println(minute);
        // 秒
        int second = calendar.get(Calendar.SECOND);
        System.out.println(second);
        // 毫秒
        int millisecond = calendar.get(Calendar.MILLISECOND);
        System.out.println(millisecond);
        // 一周的第几天  从周日开始是第一天
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        System.out.println(dayOfWeek);
        // 一年的第几天
        int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
        System.out.println(dayOfYear);
        // 一个月的第几周
        int weekOfMonth = calendar.get(Calendar.WEEK_OF_MONTH);
        System.out.println(weekOfMonth);
        // 一年的第几周
        int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
        System.out.println(weekOfYear);

    }
}

课堂练习:在上海某个交易所每一个月的第三周的周六进行交易,其他时间无法交易。输入一个时间的字符串,判断这个时间(2021-09-16)是否允许交易并且提示:交易未开始,交易已结束,交易正在进行中

// 输入一个时间的字符串,判断这个时间(2021-09-16)是否允许交易并且提示:交易未开始,交易已结束,交易正在进行中
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        // 用户输入的字符串转换成日期
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = simpleDateFormat.parse(str);
        // 把日期设置给日历
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 获取周
        int week = calendar.get(Calendar.WEEK_OF_MONTH);
        // 获取日
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        // 判断交易状态
        if (week == 3 && day == 7){
            System.out.println("交易正在进行中");
        }else if (week < 3 || (week == 3 && day < 7)){
            System.out.println("交易未开始");
        }else {
            System.out.println("交易已经结束");
        }

1.3 java.time

在jdk1.8中,对时间体系进行了新的划分,将日期和时间以及其他的信息进行分割,从而分出来一个代表时间的包--java.time

1.3.1 Instant

Instant可以精确到纳秒,Date精确到毫秒

Instant表示时间线上的瞬间点,采用UTC时间刻度

Instant代表的是一个时间,并不包括时区的概念。

public static void main(String[] args) {
        // 默认获取的是世界时间
        Instant instant = Instant.now(Clock.offset(Clock.systemUTC(), Duration.ofHours(8)));
        // 加8个小时 到北京时间
//        Instant instant = now.plusSeconds(8 * 60 * 60);
//        Instant instant = now.plus(8, ChronoUnit.HOURS);
        System.out.println(instant);
        

        // 毫秒
        System.out.println(instant.get(ChronoField.MILLI_OF_SECOND));
        // 微妙
        System.out.println(instant.get(ChronoField.MICRO_OF_SECOND));
        // 纳秒
        System.out.println(instant.get(ChronoField.NANO_OF_SECOND));
    }

1.3.2 LocalDate

只有日期而没有时间

		// 只有日期没有时间
        LocalDate date = LocalDate.now();
        System.out.println(date);
        // 指定日期
        LocalDate date1 = LocalDate.of(1998, 10, 1);
        System.out.println(date1);
        //添加日期
        date1 = date1.plus(3, ChronoUnit.YEARS);
        System.out.println(date1);
        // 减少日期
        date1 = date1.minus(3,ChronoUnit.DAYS);
        System.out.println(date1);

1.3.3 LocalTime

// 获取时间  精确到纳秒
        LocalTime time = LocalTime.now();
        System.out.println(time);
        // 指定时间
        LocalTime time1 = LocalTime.of(10,9,1);
        System.out.println(time1);
        // 添加时间
        System.out.println(time1.plus(3,ChronoUnit.HOURS));
        // 减少时间
        System.out.println(time1.minus(4,ChronoUnit.MINUTES));

1.3.4 LocalDateTime

// 年月日时分秒 纳秒
        // 获取当前时间
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);
        // 指定时间
        LocalDateTime localDateTime1 = LocalDateTime.of(2022, 12, 12, 12, 12, 12);
        System.out.println(localDateTime1);

        // 添加时间
        System.out.println(localDateTime1.plus(3, ChronoUnit.DAYS));
        // 减少时间
        System.out.println(localDateTime1.minus(5,ChronoUnit.MINUTES));

        //LocalDateTime和String的转换
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH时mm分ss秒");
        String format = formatter.format(localDateTime1);
        System.out.println(format);

        // 字符串转换成LocalDateTime
        LocalDateTime parse = LocalDateTime.parse("2022-05-06 12时11分11秒", formatter);
        System.out.println(parse);

1.3.5 间隔相关的日期类

  • Period:用于计算两个"日期"间隔
  • Duration:用于计算两个"时间"间隔
private static void demo4() {
        LocalDateTime t1 = LocalDateTime.now();
        LocalDateTime t2 = LocalDateTime.of(2027,10,1,0,0,0);

        Duration between1 = Duration.between(t1,t2) ;
        System.out.println(between1);
        System.out.println("相差的总天数" +between1.toDays());
        System.out.println("相差的总小时数" + between1.toHours());
        System.out.println("相差的总分钟数" + between1.toMinutes());
        System.out.println("相差的总秒数" + between1.toSeconds());
        System.out.println("相差的总毫秒数" + between1.toMillis());
        System.out.println("相差的总纳秒数" + between1.toNanos());

    }

    private static LocalDate demo5() {
        LocalDate t1 = LocalDate.now();
        LocalDate t2 = LocalDate.of(2027, 12, 5);
        Period between = Period.between(t1, t2);
        System.out.println("相差的年数" + between.getYears());
        System.out.println("相差的月数" + between.getMonths());
        System.out.println("相差的天数" + between.getDays());
        return t1;
    }

2 异常

2.1 异常介绍

异常的顶级父类是Throwable,包含了两大子类Error和Exception

  • Error(错误)
    • 程序中出现了非常严重的问题,一般不修改源代码不能继续执行了
  • Exception(异常)
    • 程序中出现了不太严重的问题,处理后,程序可以继续执行
    • 异常分为编译时异常和运行时异常
    • RuntimeException和它的子类
    • 除了运行时异常,其他都是编译时异常

2.2 异常产生的原因

image-20250704153220213

 public static void main(String[] args) throws ParseException {
        int[] arr = {1,2,3,4,5};
        getElement(null);

    }

    public static int getElement(int[] arr) throws ParseException {
        
        if (true){
            throw new ParseException("dfdf",0);
        }
        // 防止空指针
        if (arr == null){
            throw new NullPointerException("arr是null");
        }
        // 防止数组越界
        if (arr.length < 6)
            throw new IndexOutOfBoundsException("数组的长度不合法");

        return arr[5];
    }

2.3 自定义异常

自定义异常,定义一个类继承异常(可以是编译时异常,也可以是运行时异常),在类中提供无参构造方法和有参构造方法,有参构造方法中调用父类的构造方法,把参数传递给父类

// 自定义异常
// 继承Exception后是一个编译时异常
class PathNotExistException extends Exception{
    public PathNotExistException(){}

    public PathNotExistException(String message){
        super(message);
    }
}

class FileFormatException extends Exception{
    public FileFormatException(){}

    public FileFormatException(String message){
        super(message);
    }
}

2.4 异常的捕获方式

1 如果出现了多个异常,并且每一个异常的处理方式都不一样,可以使用多个catch分别捕获分别处理

2 如果所有异常的处理方式都一样,可以捕获这些异常的共同的父类,然后进行统一处理

try {
             s = readTxt(null);
        }catch (Exception e){
            System.out.println("异常被处理了" + e.getMessage());
            // 打印异常的栈轨迹
            e.printStackTrace();
        }

3 在jdk1.7特性:如果异常的处理进行了分组,那么同一组异常之间用|隔开,从而进行分组处理

String s = null;
        try {
             s = readTxt(null);
        }catch (PathNotExistException | FileFormatException e){// 分组处理
            System.out.println("异常被处理了" + e.getMessage());
            // 打印异常的栈轨迹
            e.printStackTrace();
        }catch (NullPointerException e){
            e.printStackTrace();
        }

注意:捕获异常的时候需要先捕获子类异常再捕获父类异常

String s = null;
        try {
             s = readTxt(null);
        } catch (PathNotExistException | FileFormatException e){// 分组处理
            System.out.println("异常被处理了" + e.getMessage());
            // 打印异常的栈轨迹
            e.printStackTrace();
        }catch (NullPointerException e){
            e.printStackTrace();
        }catch (Exception e){
            
        }

2.5 异常对方法重写重载的影响

  • 异常对方法的重载没有影响
class A{
    public void m()throws IOException {
        System.out.println("a m");
    }
    public void m(int i) throws FileNotFoundException {
        System.out.println("a m");
    }
    
}
  • 运行时异常对于重写没有影响
class A{
    public void m()throws NullPointerException {
        System.out.println("a m");
    }
    

}
class B extends A{
    @Override
    public void m()throws RuntimeException{

    }
}
  • 方法重写的时候,子类抛出的编译时异常不能超过父类对应方法的编译时异常的范围
class A{
    public void m()throws IOException {
        System.out.println("a m");
    }


}
class B extends A{
    @Override
    public void m()throws Exception{

    }
}
重载是指在同一个类中存在方法名一致而参数列表不同的方法。重载和修饰符,返回值类型以及异常都没有关系。重载本身是一种编译时多态

重写是指在父子类中存在了方法签名一致的非静态方法。在构成重写的时候,要求子类重写的方法的权限修饰符的范围要大于等于父类对应方法的权限修饰符的范围。如果父类方法的返回值类型是基本数据类型和void,那么要求子类方法的返回值类型要和父类保持一致。如果父类方法的返回值类型是引用数据类型,那么要求子类方法的返回值类型要么和父类一致,要么是父类方法返回值类型的子类。另外,子类重写的方法抛出的编译时异常不能超过父类对应方法的编译时异常的范围。重写本身是一种运行时多态。

3 finally

finally -- 表示无论是否出现异常代码都会执行

package cn.javasm.demo;

/**
 * @className: TestDemo8
 * @description:
 * @author: gfs
 * @date: 2025/7/4 16:57
 * @version: 0.1
 * @since: jdk17
 */
public class TestDemo8 {
    public static void main(String[] args) {
//        try {
//            System.out.println(1 / 1);
//        }catch (Exception e){
//            e.printStackTrace();
//        }finally {
//            System.out.println("over~");
//        }

        // finally能和try-catch连用,也可以和try连用
        // try-catch连用的时候,认为try中的代码不一定执行成功
        System.out.println(demo2());
        System.out.println(demo3());
        System.out.println(demo4());
    }

    public static int demo(){
        try {
            return 1;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            return 2;
        }
    }

    // 返回值是3
    public static int demo1(){
        try {
            return 1;
        }finally {
            try {
                return 2;
            }finally {
                return 3;
            }
        }
    }

    public static int demo2(){
        int i = 7;
        try {
            // 代码和编译和运行是从上到下执行的
            // 先进入到try代码中,获取i的值是7,由于++符号在i的后面
            // 所以JVM先标记i的值是7,然后再进行自增运算 i的值变为8
            // 在要return标记值7的时候,受到try的影响,要检查代码是否有finally
            // 检查到有finally,继续执行i++,i的值变成了9.然后打印i就是9
            // finally执行完毕,然后返回标记的值7
            return i++;
        }finally {
            i++;
            System.out.println("finally中i的值是" + i);
        }
    }

    // 返回的是地址
    public static Person demo3(){
        Person person = new Person();
        try {
            person.setName("丁真");
            person.setAge(23);
            person.setAddress("理塘");
            return person;
        }finally {
            person = new Person();
            person.setName("王源");
            person.setAge(26);
            person.setAddress("重庆");
        }
    }

    public static String demo4(){
        String str;
        try {
            str = "abc";
            return str;
        }finally {
            // 地址已经发生改变
            str = "def";
        }
    }
}

JDK5部分特性:自动封箱拆箱,增强for循环,可变参数,枚举,注解,泛型,静态导入,反射...

  • 可变参数
public static void main(String[] args) {
        System.out.println(sum(4,5,6,7,78,6,5,6,56,5,6,5,65,6,56));
    }

    // 定义一个求和方法
    // 可变参数 本质上就是一个数组,是一种语法糖 是JDK5的特性
    // 参数个数是不固定的
    // 可变参数在参数列表中只能有一个,并且必须放在参数列表的末尾
    public static int sum(int a,int... arr){
        int sum = 0;
        for (int i : arr) {
            sum += i;
        }
        return sum;
    }
  • 静态导包
// 静态导包
import static java.util.Arrays.sort;

/**
 * @className: TestDemo9
 * @description:
 * @author: gfs
 * @date: 2025/7/4 17:21
 * @version: 0.1
 * @since: jdk17
 */
public class TestDemo9 {
    public static void main(String[] args) {
//        System.out.println(sum(4,5,6,7,78,6,5,6,56,5,6,5,65,6,56));
        int[] arr = {3,2,5,1,6};
        sort(arr);
    }
posted @ 2025-07-05 10:34  小胡coding  阅读(22)  评论(0)    收藏  举报