> 文章列表 > 日期类的讲解与常用类习题

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

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

目录

第一代日期

第二代日期类

第三代日期类

第三代日期类常见方法

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_DAYCalendar 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转成 DateDate 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') {//如果发现有一个小数不符合条件那么就返回falsereturn 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方法判断地址是否相同,所以返回falseSystem.out.println(a.name == b.name);//指向的都是常量池中的地址String s4 = new String("jack");String s5 = "jack";System.out.println(s1 == s4);//s1是常量池中的地址  s4是指向堆中的地址 所以返回falseSystem.out.println(s4 == s5);//s4是指向堆中的地址  s5时 常量池中的地址  所以返回falseString t1 = "hello" + s1;//t1是变量和常量相加// 在底层会先执行  先 创建一个 StringBuilder sb = StringBuilder()//在执行  sb.append()方法//最调用最后调用toString 方法最后的是new也就是指向了堆中的value空间  value空间指向常量池中的hellohspeduString 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出来的,所以是两个不同的对象,而==在判断引用类型的时候,判断的是地址是否相同,所以返回的是false5.在判断 a.equals(b)的时候,因为Animal没有重写equals方法,所以默认使用的是Object的equals方法,而Object的equals方法判断的是两个是否为同一个对象很显然,a  和  b都是new出来的,在堆中有独立的空间,所以返回false6.在判断 a.name == b.name的时候,因为String已经重写了equals方法,所以这里判断的是内容是否相同,所以返回true7.在执行这句话的时候,String s4 = new String("jack"); s4指向的是堆中的空间,堆中有一个value属性,指向常量池中的jack,因为Jack已经在常量池中存在了,所以不会在重新创建8.在执行这句话的时候,String s5 = "jack"; s5指向的就是常量池中的地址9.在判断 s1==s4的时候,因为s1指向的是常量池中的地址,s4指向的是堆中的空间,所以返回false10.在判断 s4==s5的时候,因为s5指向的是常量池中的地址,s4指向的是堆中的空间,所以返回false11.在执行这句话的时候String t1 = "hello" + s1; 因为是常量与变量相加,在底层会创建一个StringBuffer,如果使用append()方法,最后使用toString()方法返回所以实际上,t1执行的是堆中的一块空间,然后堆中的空间在执行常量池中的hellojack12.在执行这句话的时候String t2 = "hellojack"; 因为hellojack,已经在常量池中存在了,所以不会再去创建啊新的空间13.在判断 t1.intern() == t2 的时候 因为t1.intern()返回的是常量池中的地址 而t2 执行的也是常量池中的地址,所以返回true*/}
}class Animal {String name;public Animal(String name) {this.name = name;}
}