日期类的讲解与常用类习题

目录

第一代日期类

第二代日期类

第三代日期类

第三代日期类常见方法

Instant 时间戳

本章作业

第一题

第二题

第三题

第四题

第五题


第一代日期类

1.Date:精确到毫秒,代表特定的瞬间

2.SimpleDateFormat:格式和解析日期的类SimpleDateFormat 格式化和解析日期的具体类。它允许进行格式化(日期->文本)、解析(文本->日期)和规范化.

代码演示:

package idea.chapter13.date_;

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

public class date01 {
    public static void main(String[] args) throws ParseException {

        //1. 获取当前系统时间
        //2. 这里的Date 类是在java.util包
        //3. 默认输出的日期格式是国外的方式, 因此通常需要对格式进行转换
        Date d1 = new Date(); //获取当前系统时间
        System.out.println("当前日期=" + d1);
        Date d2 = new Date(9234567); //通过指定毫秒数得到时间
        System.out.println("d2=" + d2); //获取某个时间对应的毫秒数
//

        //解读
        //1. 创建 SimpleDateFormat对象,可以指定相应的格式
        //2. 这里的格式使用的字母是规定好的,不能乱写

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
        String format = sdf.format(d1); // format:将日期转换成指定格式的字符串
        System.out.println("当前日期=" + format);

        //解读
        //1. 可以把一个格式化的String 转成对应的 Date
        //2. 得到Date 仍然在输出时,还是按照国外的形式,如果希望指定格式输出,需要转换
        //3. 在把String -> Date , 使用的 sdf 格式需要和你给的String的格式一样,否则会抛出转换异常
        //也即是  String s = "1996年01月01日 10:20:30 星期一";我们这里定义了一个日期,要和我们上面SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
        //这里的格式相同,否则会报异常
        String s = "1996年01月01日 10:20:30 星期一";
        Date parse = sdf.parse(s);//在把一个字符串转成一个Date时,可能会抛出异常,需要处理,可能会抛出一个转换异常
        System.out.println(sdf.format(parse));

    }
}

第二代日期类

1)第二代日期类,主要就是Calendar类(日历)。

public abstract class Galendar extends Object implements Serializable Cloneable, Comparable<Calendar>

2)Calendar类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

代码演示:

注意: 这里为什么要 + 1, 因为Calendar 返回月时候,是按照 0 开始编号

 如果我们需要按照 24小时进制来获取时间, Calendar.HOUR ==改成=> Calendar.HOUR_OF_DAY

package idea.chapter13.date_;

import java.util.Calendar;

/**
 * 演示第二代日期类的使用
 */
public class Calendar_ {
    public static void main(String[] args) {
        
        //1. Calendar是一个抽象类, 并且构造器是private
        //2. 可以通过 getInstance() 来获取实例
        //3. 提供大量的方法和字段提供给程序员
        //4. Calendar没有提供对应的格式化的类,因此需要程序员自己组合来输出(灵活)
        //5. 如果我们需要按照 24小时进制来获取时间, Calendar.HOUR ==改成=> Calendar.HOUR_OF_DAY
        Calendar c = Calendar.getInstance(); //创建日历类对象//比较简单,自由
        System.out.println("c=" + c);
        //2.获取日历对象的某个日历字段
        System.out.println("年:" + c.get(Calendar.YEAR));
        // 这里为什么要 + 1, 因为Calendar 返回月时候,是按照 0 开始编号
        System.out.println("月:" + (c.get(Calendar.MONTH) + 1));
        System.out.println("日:" + c.get(Calendar.DAY_OF_MONTH));
        System.out.println("小时:" + c.get(Calendar.HOUR));
        System.out.println("分钟:" + c.get(Calendar.MINUTE));
        System.out.println("秒:" + c.get(Calendar.SECOND));
        //Calender 没有专门的格式化方法,所以需要程序员自己来组合显示
        System.out.println(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DAY_OF_MONTH) +
                " " + c.get(Calendar.HOUR_OF_DAY) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND) );

    }
}

第三代日期类

前面两代日期类的不足分析

JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类

之后被弃用了。而Calendar也存在问题是

1)可变性:像日期和时间这样的类应该是不可变的。

2)偏移性:Date中的年份是从1900开始的,而月份都从0开始。

3)格式化:格式化只对Date有用,Calendar则不行。

4)此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)。

第三代日期类常见方法

1.LocalDate(日期/年月日)、LocalTime(时间/时分秒)、LocalDateTime(日期时间/年月日时分秒)JDK8加入

LocalDate只包含日期,可以获取日期字段

LocalTime只包含时间,可以获取时间字段

LocalDateTime包含日期+时间,可以获取日期和时间字段

2.DateTimeFormatter格式日期类

类似于SimpleDateFormat

DateTimeFormat dtf = DateTimeFormatter.ofPattern(格式);

String str =dtf.format(日期对象);

注意关于 DateTimeFormatter的各个格式参数,需要看jdk8的文档,因为第三代日期时在jdk8才引入的,所以需要查看jdk8的文档

代码演示:

package idea.chapter13.date_;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * 演示第三代日期类的使用
 */
public class LocalDate_ {
    public static void main(String[] args) {
        //第三代日期
        //解读
        //1. 使用now() 返回表示当前日期时间的 对象
        LocalDateTime ldt = LocalDateTime.now(); //LocalDate.now();//LocalTime.now()
        System.out.println(ldt);

        //2. 使用DateTimeFormatter 对象来进行格式化
        // 创建 DateTimeFormatter对象
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = dateTimeFormatter.format(ldt);
        System.out.println("格式化的日期=" + format);

        System.out.println("年=" + ldt.getYear());
        System.out.println("月=" + ldt.getMonth());
        System.out.println("月=" + ldt.getMonthValue());
        System.out.println("日=" + ldt.getDayOfMonth());
        System.out.println("时=" + ldt.getHour());
        System.out.println("分=" + ldt.getMinute());
        System.out.println("秒=" + ldt.getSecond());

        LocalDate now = LocalDate.now(); //可以获取年月日
        LocalTime now2 = LocalTime.now();//获取到时分秒


        //提供 plus 和 minus方法可以对当前时间进行加或者减
        //看看890天后,是什么时候 把 年月日-时分秒
        LocalDateTime localDateTime = ldt.plusDays(890);
        System.out.println("890天后=" + dateTimeFormatter.format(localDateTime));

        //看看在 3456分钟前是什么时候,把 年月日-时分秒输出
        LocalDateTime localDateTime2 = ldt.minusMinutes(3456);
        System.out.println("3456分钟前 日期=" + dateTimeFormatter.format(localDateTime2));

    }
}

Instant 时间戳

类似于Date

提供了一系列和Date类转换的方式Instant——>Date:

Date date =Date.from(instant);Date—>Instant:

Instant instant = date.tolnstant0;

案例演示:

Instant now =Instant.now0;System.out.printin(now);

Date date=Date.from(now); Instant instant = date.tolnstant0;

代码演示;

package idea.chapter13.date_;

import java.time.Instant;
import java.util.Date;

public class Instant_ {
    public static void main(String[] args) {

        //1.通过 静态方法 now() 获取表示当前时间戳的对象
        Instant now = Instant.now();
        System.out.println(now);
        //2. 通过 from 可以把 Instant转成 Date
        Date date = Date.from(now);
        //3. 通过 date的toInstant() 可以把 date 转成Instant对象
        Instant instant = date.toInstant();

    }
}

本章作业

第一题

思路分析:

首先将传入进来的字符串转换成一个字符数组

循环的结束条件,当i<j了,那么说明已经不能够继续交换了

最后重新构造一个String返回

package idea.chapter13.homework;

public class homework01 {
    public static void main(String[] args) {
        /*
        1.编程题Homework01.java
        (1)将字符串中指定部分进行反转。比如将"abcdef"反转为"aedcbf"
        (2) 编写方法 public static String reverse(String str, int start,int end)搞定
         */

        try {
            String str = reverse(null, 1, 4);
            System.out.println(str);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public static String reverse(String str, int start, int end) {

        //对一些条件进行判断,比如不允许字符串为空,长度范围限制等等
        if (!(str != null)) {
            throw new RuntimeException("字符串为空");
        } else if (!(start > 0 && end < str.length() && end > start)) {
            throw new RuntimeException("参数异常");
        }
        //首先将传入进来的字符串转换成一个字符数组
        char[] chars = str.toCharArray();
        //使用循环进行拷贝
        //循环的结束条件,当i<j了,那么说明已经不能够继续交换了
        for (int i = start, j = end; i < j; i++, j--) {
            char tmp = chars[i];
            chars[i] = chars[j];
            chars[j] = tmp;
        }

        //重新构造一个String返回
        return new String(chars);
    }
}

第二题

思路分析:

        

1.创建一个Scanner对象,接受用户的输入

2.对用户输入的初始数值进行校验,比如用户名不可以为空,用户名的长度,并且要求用户名全部都是数值

3.在对密码是否都是数字的时候,我们将其单独写一个方法进行判断

4.如果发现不合法,我们就抛出异常,然后在main方法中捕获即可

package idea.chapter13.homework;

import java.util.Scanner;

public class homework02 {
    public static void main(String[] args) {
        /*
        输入用户名、密码、邮箱,如果信息录入正确,则提示注册成功,否则生成异常对象
        (1)用户名长度为2或3或4
        (2)密码的长度为6,要求全是数字
        (3)邮箱中包含@和.并且@在.的前面 isDigital
         */

        /*
        思路分析:
        1.创建一个Scanner对象,接受用户的输入
        2.对用户输入的初始数值进行校验,比如用户名不可以为空,用户名的长度,并且要求用户名全部都是数值
        3.在对密码是否都是数字的时候,我们将其单独写一个方法进行判断
        4.如果发现不合法,我们就抛出异常,然后在main方法中捕获即可
         */

        Scanner scanner = new Scanner(System.in);
        try {
            System.out.print("请输入用户名:");
            String username = scanner.next();
            System.out.print("请输入密码:");
            String passwd = scanner.next();
            System.out.print("请输入邮箱:");
            String email = scanner.next();

            checkUsername(username, email, passwd);
            System.out.println("注册成功");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }


    }

    //编写方法,校验用户名是否合法
    public static void checkUsername(String username, String email, String passwd) {

        //对初始的数值进行校验
        if (!(username != null || passwd != null || email != null)) {//判断是否为空
            throw new RuntimeException("输入的名字不能为空");
        }

        if (!(username.length() >= 2 && username.length() <= 4)) {
            throw new RuntimeException("用户名长度应在2-4之间");
        }

        if (!(passwd.length() == 6 && isDigital(passwd))) {
            throw new RuntimeException("密码的长度为6,要求全是数字");
        }


        //校验邮箱
        //indexOf()方法,会去字符串中查找,是否有该字符,如果查找不到,就返回-1,也说明我们输入的邮箱不合法
        int index = email.indexOf("@");
        if (index == -1) {
            throw new RuntimeException("没有@字符");
        }
        //查找到的是.最后一次出现位置的索引
        int n1 = email.lastIndexOf(".");
        //如果index大于了n1说明,@符号已经在.的后面了
        if (index > n1) {
            throw new RuntimeException("@符号要在.的前面");
        }

    }

    public static boolean isDigital(String passwd) {
        char[] chars = passwd.toCharArray();//想将字符串转换成一个数组
        for (int i = 0; i < chars.length; i++) {//在for循化遍历
            if (chars[i] < '0' || chars[i] > '9') {//如果发现有一个小数不符合条件那么就返回false
                return false;
            }
        }
        return true;//在for循化遍历完之后,还没有返回说明密码全部都是数字
    }
}

第三题

思路分析:

package idea.chapter13.homework;

public class homework03 {
    public static void main(String[] args) {
        /*
        3.编程题Homework03.java
        (1)编写java程序,输入形式为:Han shun Ping的人名,以Ping,Han.S的形式打印
        出来 其中.S是中间单词的首字母。
        (2)例如输入“Willian Jefferson Clinton" 输出形式为:Clinton,Willian J
         */
        String name = "Willian Jefferson Clinton";
        printName(name);
    }

    public static void printName(String name) {
        if (name == null) {
            System.out.println("输入的名字不可以为空");
            return;
        }
        String[] s = name.split(" ");//使用split方法进行分割按照空格分割
        /*
        把name进行分割之后相当于就是把字符串分成了三个部分存到数组中
        s[0]=Willian  s[1]=Jefferson    s[2]=Clinton
        然后在按照格式进行输出
         */
        if (s.length != 3) {//如果分割之后格式不是三个部分就提示信息
            System.out.println("输入的格式不正确");
            return;
        }
        //使用format格式字符串输出信息  在进行最后一个字符输出的时候先将字符串全部转换成大写,然后在.charAt(0)拿到第一个字符
        String format = String.format("%s,%s .%c", s[2], s[0], s[1].toUpperCase().charAt(0));
        System.out.println(format);
    }
}

第四题

思路分析:

1.将传入的字符串,装换成一个字符数组,然后使用循环进行比较判断即可

package idea.chapter13.homework;

public class homework04 {
    public static void main(String[] args) {
        /*
        4.编程题Homework04.java
        输入字符串,判断里面有多少个大写字母,多少个小写字母,多少个数字
         */

        String str = "123asdASD ";

        count(str);
    }
    
    public static void count(String str) {
        if (str == null) {
            System.out.println("输入的字符串不可以为空");
            return;
        }
        int a = 0;//记录大写字母
        int b = 0;//记录小写字母
        int c = 0;//记录数字
        int otherNum = 0;//表示其他字符
        //注意:这里要将字符串,装换成一个字符数组,然后使用在循环,进行判断
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] >= 'A' && chars[i] <= 'Z') {
                a++;
            } else if (chars[i] >= 'a' && chars[i] <= 'z') {
                b++;
            } else if (chars[i] >= '0' && chars[i] <= '9') {
                c++;
            } else {
                otherNum++;
            }
        }
        System.out.println("大写字母有" + a + "\n小写字母有" + b + "\n数字的个数有" + c + "\n其他字符有" + otherNum);
    }
}

第五题

思路分析:

        1.在执行这句话的时候,String s1 = "jack"; s1指向的是常量池中的空间
        2.在执行这句话的时候,Animal a = new Animal(s1); //a指向堆中的空间,堆中的空间,在指向常量池中的jack  要注意a 和 b在堆中是两个单独的对象是不同的
        3.在执行这句话的时候,Animal b = new Animal(s1); //b指向堆中的空间,堆中的空间,在指向常量池中的jack  要注意a 和 b在堆中是两个单独的对象是不同的

        4.在判断 a==b 的时候,因为两个对象都是new出来的,所以是两个不同的对象,而==在判断引用类型的时候,判断的是地址是否相同,所以返回的是false
        5.在判断 a.equals(b)的时候,因为Animal没有重写equals方法,所以默认使用的是Object的equals方法,而Object的equals方法判断的是两个是否为同一个对象
          很显然,a  和  b都是new出来的,在堆中有独立的空间,所以返回false
        6.在判断 a.name == b.name的时候,因为String已经重写了equals方法,所以这里判断的是内容是否相同,所以返回true

        7.在执行这句话的时候,String s4 = new String("jack"); s4指向的是堆中的空间,堆中有一个value属性,指向常量池中的jack,因为Jack已经在常量池中存在了,所以不会在重新创建
        8.在执行这句话的时候,String s5 = "jack"; s5指向的就是常量池中的地址

        9.在判断 s1==s4的时候,因为s1指向的是常量池中的地址,s4指向的是堆中的空间,所以返回false
        10.在判断 s4==s5的时候,因为s5指向的是常量池中的地址,s4指向的是堆中的空间,所以返回false

        11.在执行这句话的时候String t1 = "hello" + s1; 因为是常量与变量相加,在底层会创建一个StringBuffer,如果使用append()方法,最后使用toString()方法返回
           所以实际上,t1执行的是堆中的一块空间,然后堆中的空间在执行常量池中的hellojack
        12.在执行这句话的时候String t2 = "hellojack"; 因为hellojack,已经在常量池中存在了,所以不会再去创建啊新的空间

        13.在判断 t1.intern() == t2 的时候 因为t1.intern()返回的是常量池中的地址 而t2 执行的也是常量池中的地址,所以返回true

package idea.chapter13.homework;

public class homework05 {
    public static void main(String[] args) {
        String s1 = "jack";
        Animal a = new Animal(s1);
        Animal b = new Animal(s1);
        System.out.println(a == b);//因为a和b是new出来的指向的都是堆中不同的空间
        System.out.println(a.equals(b));//因为Animal没有重写equals方法所以默认使用的还是object的equals方法判断地址是否相同,所以返回false
        System.out.println(a.name == b.name);//指向的都是常量池中的地址
        String s4 = new String("jack");
        String s5 = "jack";

        System.out.println(s1 == s4);//s1是常量池中的地址  s4是指向堆中的地址 所以返回false
        System.out.println(s4 == s5);//s4是指向堆中的地址  s5时 常量池中的地址  所以返回false

        String t1 = "hello" + s1;
        //t1是变量和常量相加
        // 在底层会先执行  先 创建一个 StringBuilder sb = StringBuilder()
        //在执行  sb.append()方法
        //最调用最后调用toString 方法最后的是new也就是指向了堆中的value空间  value空间指向常量池中的hellohspedu


        String t2 = "hellojack";
        System.out.println(t1.intern() == t2);//t1.intern返回的常量池中的地址   因为t1已经在常量池中创建了hellohspedu所以不会在创建新的空间 因此指向的也是常量池中的空间所以返回 一个true
        /*
        思路分析:
        1.在执行这句话的时候,String s1 = "jack"; s1指向的是常量池中的空间
        2.在执行这句话的时候,Animal a = new Animal(s1); //a指向堆中的空间,堆中的空间,在指向常量池中的jack  要注意a 和 b在堆中是两个单独的对象是不同的
        3.在执行这句话的时候,Animal b = new Animal(s1); //b指向堆中的空间,堆中的空间,在指向常量池中的jack  要注意a 和 b在堆中是两个单独的对象是不同的

        4.在判断 a==b 的时候,因为两个对象都是new出来的,所以是两个不同的对象,而==在判断引用类型的时候,判断的是地址是否相同,所以返回的是false
        5.在判断 a.equals(b)的时候,因为Animal没有重写equals方法,所以默认使用的是Object的equals方法,而Object的equals方法判断的是两个是否为同一个对象
          很显然,a  和  b都是new出来的,在堆中有独立的空间,所以返回false
        6.在判断 a.name == b.name的时候,因为String已经重写了equals方法,所以这里判断的是内容是否相同,所以返回true

        7.在执行这句话的时候,String s4 = new String("jack"); s4指向的是堆中的空间,堆中有一个value属性,指向常量池中的jack,因为Jack已经在常量池中存在了,所以不会在重新创建
        8.在执行这句话的时候,String s5 = "jack"; s5指向的就是常量池中的地址

        9.在判断 s1==s4的时候,因为s1指向的是常量池中的地址,s4指向的是堆中的空间,所以返回false
        10.在判断 s4==s5的时候,因为s5指向的是常量池中的地址,s4指向的是堆中的空间,所以返回false

        11.在执行这句话的时候String t1 = "hello" + s1; 因为是常量与变量相加,在底层会创建一个StringBuffer,如果使用append()方法,最后使用toString()方法返回
           所以实际上,t1执行的是堆中的一块空间,然后堆中的空间在执行常量池中的hellojack
        12.在执行这句话的时候String t2 = "hellojack"; 因为hellojack,已经在常量池中存在了,所以不会再去创建啊新的空间

        13.在判断 t1.intern() == t2 的时候 因为t1.intern()返回的是常量池中的地址 而t2 执行的也是常量池中的地址,所以返回true
         */
    }
}

class Animal {
    String name;

    public Animal(String name) {
        this.name = name;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值