目录
第一代日期类
第二代日期类
第三代日期类
第三代日期类常见方法
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方法,所以这里判断的是内容是否相同,所以返回true7.在执行这句话的时候,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指向的是堆中的空间,所以返回false11.在执行这句话的时候String t1 = "hello" + s1; 因为是常量与变量相加,在底层会创建一个StringBuffer,如果使用append()方法,最后使用toString()方法返回
所以实际上,t1执行的是堆中的一块空间,然后堆中的空间在执行常量池中的hellojack
12.在执行这句话的时候String t2 = "hellojack"; 因为hellojack,已经在常量池中存在了,所以不会再去创建啊新的空间文章来源:https://www.toymoban.com/news/detail-421418.html13.在判断 t1.intern() == t2 的时候 因为t1.intern()返回的是常量池中的地址 而t2 执行的也是常量池中的地址,所以返回true文章来源地址https://www.toymoban.com/news/detail-421418.html
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;
}
}
到了这里,关于日期类的讲解与常用类习题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!