目录
1 Math 类
Math 包含执行基本数学运算的方法
Math中方法的调用方式:Math类的构造方法被private
修饰,但内部的方法都是静态的,则可以通过类名.方法名
进行调用
🌈 Math类的常用方法
Math.PI
代表近似的圆周率常量(double)
Math.E
代表自然对数的底数e(double)
🙋举个栗子:
public static void main(String[] args) {
int abs = Math.abs(-10);
System.out.println(abs); // 10
double ceil = Math.ceil(10.9);
System.out.println(ceil); // 11.0
double floor = Math.floor(10.9);
System.out.println(floor); // 10.0
long round = Math.round(10.5);
System.out.println(round); // 11
int max = Math.max(12, 13);
System.out.println(max); // 13
int min = Math.min(12, 13);
System.out.println(min); // 12
double pow = Math.pow(3, 2);
System.out.println(pow); // 9.0
double random = Math.random();
System.out.println(random); // 返回[0.0,1.0)之间的随机数
System.out.println(Math.E); // 2.718281828459045
System.out.println(Math.PI); // 3.141592653589793
}
2 System类
System类的功能是通用的,都是通过类名直接调用即可,不能实例化
🌈 System 类的常用方法
🙋举个栗子:
public class SystemDemo {
public static void main(String[] args) {
// System.exit(0); //终止当前运行的 Java 虚拟机,非零表示异常终止
// long start = System.currentTimeMillis();//获取当前时间
// //System.out.println(l);
// for (int i = 0; i < 10000; i++) {
// System.out.println(i);
// }
// long end = System.currentTimeMillis();//获取当前时间
// System.out.println(end - start);//472,得到的就是这个for循环运行的时间.
// arraycopy(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数) 数组copy
int [] arr1 = {1,2,3,4,5};
int [] arr2 = new int[10];
//需求:我要把arr1中的数据拷贝到arr2中.
System.arraycopy(arr1,0,arr2,0,arr1.length);
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
时间毫秒值
- 计算机认为时间是有起点的,起始时间:
1970年1月1日 00:00:00
(1970年1月1日是C语言的生日),System.currentTimeMillis()
返回起始时间到此时的总的毫秒值
3 Object类
3.1 Object 类概述
每个类都可以将Object类作为父类,所有类都直接或间接的继承自该类
Object类的构造方法:public Object()
回想面向对象中,为什么说子类的构造方法默认访问的是父类的无参构造方法?
- 因为它们的顶级父类只有无参构造方法
Object
类的常用方法
3.2 toString()方法
toString()
方法默认返回的是当前对象在内存中的地址信息:类的全限名@内存地址
💢 但是
- 开发中直接输出对象,默认输出对象的地址其实是毫无意义的
- 开发中输出对象变量,更多的时候是希望看到对象的内容数据而不是对象的地址信息
此时,我们就可以明白,父类Object
的toString()
方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址信息!!
🙋举个栗子:
class Student extends Object {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class ObjectDemo {
public static void main(String[] args) {
Student s = new Student();
s.setName("林青霞");
s.setAge(30);
System.out.println(s); // Student{name='林青霞',age=30}
System.out.println(s.toString()); // Student{name='林青霞',age=30}
}
}
☀️ 结论:
- 直接打印一个对象就相当于打印这个对象的
toString
方法的返回值object
类的toString
方法得到的是对象的地址值,我们一般会对toString
方法进行重写,从而得到对象的属性值
3.3 equals()方法
Object
类中的 equals
方法,默认是比较当前对象与另一个对象的地址是否相同,底层使用的是==
,比较的是对象的地址值,要区别于 String
中基于内容比较的 equals
方法,Object
类中的 equals
方法重写之后才是基于内容比较的。
父类Object
的equals()
方法存在的意义就是为了被子类重写,以便子类自己来定制比较规则
🙋举个栗子:
Student类
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/*
重写equals方法的方式:
1. alt + insert 选择equals() and hashCode(),IntelliJ Default,一路next,finish即可
2. 在类的空白区域,右键 -> Generate -> 选择equals() and hashCode(),后面的同上。
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
public class Demo {
public static void main(String[] args) {
Student s1 = new Student("zhangsan",23);
Student s2 = new Student("zhangsan",23);
// == 比较的是地址值
System.out.println(s1 == s2);//false
//Object类中的equals方法,底层也是用==号比较地址值。重写equals()方法可以比较内容,也即是对象的属性值,此时System.out.println(s1.equals(s2));的值为true
System.out.println(s1.equals(s2));//true
}
}
💥 常见面试题
public class InterviewTest {
public static void main(String[] args) {
String s1 = "abc";
StringBuilder sb = new StringBuilder("abc");
//1.此时调用的是String类中的equals方法.
//保证参数也是字符串,否则不会比较属性值而直接返回false
System.out.println(s1.equals(sb)); // false
//StringBuilder类中是没有重写equals方法,用的就是Object类中的.
System.out.println(sb.equals(s1)); // false
}
}
4 Objects类
Objects
类与Object
类还是继承关系(一切类都是Object
类的子类),Object
类是从 JDK 1.7 之后才开始有的
🌈 Objects
类的常用方法
🙋举个栗子:
学生类
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
//System.out.println("看看我执行了吗?");
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
import java.util.Objects;
public class Demo {
public static void main(String[] args) {
Student s1 = new Student("小罗同学", 50);
String result1 = Objects.toString(s1);
System.out.println(result1); // Student{name='小罗同学', age=50}
System.out.println(s1); // Student{name='小罗同学', age=50}
// Student s2 = new Student("小花同学",23);
Student s2 = null;
// 返回对象的字符串表示形式。如果对象为空,那么返回第二个参数.
String result2 = Objects.toString(s2, "随便写一个");
System.out.println(result2); // 随便写一个
// Student s3 = null;
Student s3 = new Student();
boolean result3 = Objects.isNull(s3);
System.out.println(result3); // false
//Student s4 = new Student();
Student s4 = null;
boolean result4 = Objects.nonNull(s4);
System.out.println(result4); // false
}
}
另外,Objects
类还有一个重要的方法:
public static boolean equals(Object a,Object b)
:比较两个对象,底层会先进行非空判断,从而可以避免空指针异常,再进行 equals
比较
Objects
类的 equal
方法和Object
的 equal
方法比较结果是一样的,但是更安全。
🙋举个栗子:
public class Test {
public static void main(String[] args) {
Student s1=null;
Student s2=new Student("哈哈",23);
// System.out.println(s1.equals(s2)); // 报错,空指针异常
System.out.println(Objects.equals(s1,s2)); // false
}
}
5 BigDecimal类
BigDecimal类的作用:用于解决浮点型运算精度失真的问题,可以用来进行精确计算
创建BigDecimal
对象封装浮点型数据(最好的方式是调用方法valueOf
)
public static BigDecimal valueOf(double val)
:包装浮点数成为 BigDecimal
对象
🙋举个栗子:
import java.math.BigDecimal;
public class Demo {
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal(10.0); // 如果是整数则自动去掉小数点
// 如果是字符串则自动去掉双引号,而且字符串里面只能是数字
BigDecimal bd2 = new BigDecimal("0.3");
BigDecimal bd3 = new BigDecimal("300.0");
System.out.println(bd1);// 10
System.out.println(bd2);// 0.3
System.out.println(bd3);// 300.0
// 调用方法创建BigDecimal对象
double a=0.1;
double b=0.2;
double c=a+b;
System.out.println(c); // 0.30000000000000004
BigDecimal a1=BigDecimal.valueOf(a);
BigDecimal b1=BigDecimal.valueOf(b);
BigDecimal c1=a1.add(b1);
// BigDecimal c1=a1+b1; 错误写法
System.out.println(c1); //0.3
}
}
🎈 构造方法创建BigDecimal
对象的区别:
- 参数为字符串的构造方法是精确计算,较为推荐使用
- 不推荐使用构造方法
BigDecimal(double)
的方式把double
值转为BigDecimal
对象BigDecimal(double)
存在精度风险,在精确计算或值比较的场景中可能会导致业务逻辑异常
import java.math.BigDecimal;
public class Demo {
public static void main(String[] args) {
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
BigDecimal bd3 = bd1.add(bd2);
System.out.println(bd3);// 0.3
BigDecimal bd4 = new BigDecimal(0.1);
BigDecimal bd5 = new BigDecimal(0.2);
BigDecimal bd6 = bd4.add(bd5);
System.out.println(bd6);// 0.3000000000000000166533453693773481063544750213623046875
}
}
🌈 常用方法
使用方法同上的add
,不再赘述
❗️注意:
BigDecimal
一定是要 精度 计算的
🙋举个栗子:
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Demo {
public static void main(String[] args) {
/* 会报错,因为【字符串构造方法是精确计算,使用valueOf方法同样会报错】,而 10.0/3.0 的结果是无限循环小数,永远计算不完
BigDecimal bd1 = new BigDecimal("10.0");
BigDecimal bd2 = new BigDecimal("3.0");
BigDecimal divide = bd1.divide(bd2);
System.out.println(divide);
*/
BigDecimal bd1 = BigDecimal.valueOf(10.0);
BigDecimal bd2 = BigDecimal.valueOf(3.0);
// 参数一:除数,参数二:保留的小数位数,参数三:舍入模式
BigDecimal rs = bd1.divide(bd2,2, RoundingMode.HALF_UP);
System.out.println(rs); // 3.33
}
}
同样,
BigDecimal
只是一种计算的手段,我们的最终目的还是要转成double
,使用doubleValue()
方法
import java.math.BigDecimal;
public class Demo {
public static void main(String[] args) {
BigDecimal a1=BigDecimal.valueOf(0.1);
BigDecimal b1=BigDecimal.valueOf(0.2);
BigDecimal c1=a1.add(b1);
System.out.println(c1); //0.3
double v = c1.doubleValue();
System.out.println(v); // 0.3
}
}
6 时间日期类
计算机中的时间原点为:1970年1月1日 00:00:00,中国的标准时间为北京时间,北京位于东八区,需要在世界标准时间的基础上+8。
6.1 Date类
Date 代表了一个特定的时间,精确到毫秒
💕 Date类的构造方法
🙋举个栗子:
public static void main(String[] args) {
//那么这个时间就表示电脑中的当前时间。
Date date1 = new Date();
System.out.println(date1);
//从计算机的时间原点开始,过了指定毫秒的那个时间。
Date date2 = new Date(0L);
System.out.println(date2); //Thu Jan 01 08:00:00 CST 1970
//从时间原点开始,过了0毫秒。
//因为我们是在中国,我们是在东八区需要+8小时。
//1970年1月1日 上午的9点
Date date3 = new Date(3600L * 1000);
System.out.println(date3); //Thu Jan 01 09:00:00 CST 1970
}
🌈 Date
类的常用方法
🙋举个栗子:
public static void main(String[] args) {
//method1();
//method2();
}
private static void method2() {
// 时间毫秒值恢复成日期对象有两种方式
// Date date1 = new Date(时间毫秒值);
// setTime(时间毫秒值);
Date date1 = new Date();
date1.setTime(0L);
System.out.println(date1);//Thu Jan 01 08:00:00 CST 1970
}
private static void method1() {
//把当前时间封装成一个date对象
Date date1 = new Date();
//获取这个date对象的毫秒值 --- 获取当前时间的毫秒值
long time = date1.getTime();
System.out.println(time);
long time2 = System.currentTimeMillis();
System.out.println(time2);
//这两种方法是一样的
}
6.2 SimpleDateFormat类
SimpleDateFormat
是一个具体的类,用于以区域设置敏感的方式 格式化 和 解析 日期。
- 可以对
Date
对象或时间毫秒值格式化成我们喜欢的时间格式 - 也可以把字符串的时间形式解析成日期对象
常用的模式字母以及对应关系如下:
- y —— 年
- M —— 月
- d —— 日
- H —— 时
- m —— 分
- s —— 秒
举例:
- 2022-11-27 14:09:39 —— yyyy-MM-dd HH:mm:ss
- 2022年11月27日 14:09:39 —— yyyy年MM月dd日 HH:mm:ss
💕 SimpleDateFormat
类的构造方法
😀 SimpleDateFormat
类常用方法
- 格式化(从Date到String)
public final String format(Date date)
:将日期格式化成日期/时间字符串public final String format(Object time)
:将时间毫秒值化成日期/时间字符串
- 解析(从String到Date)
public Date parse(String source)
:从给定字符串的开始解析文本以生成日期
🙋举个栗子:
public static void main(String[] args) throws ParseException {
//当前时间的Date对象
Date date1 = new Date();
//创建了一个日期格式。
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); // 2022年11月27日 14:51:51
// SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日"); // 2022年11月27日
// SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); // 2022-11-27
// SimpleDateFormat sdf1 = new SimpleDateFormat(); // 22-11-27 下午2:51
// 1. 格式化日期对象
String result1 = sdf1.format(date1);
System.out.println(result1);
// 2. 格式化时间毫秒值,例如:121秒之后的时间是?
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
long time=System.currentTimeMillis()+121*1000;
String ss = sdf.format(time);
System.out.println(ss);
// 解析字符串时间成为日期对象
String s = "2022-01-01";
// SimpleDateFormat参数的格式必须和字符串一致
//SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
Date date2 = sdf2.parse(s);
System.out.println(date2); // Sat Jan 01 00:00:00 CST 2022
}
😎 应用案例:
秒杀开始时间是2020年11月11日 00:00:00,结束时间是2020年11月11日 00:10:00,用户小贾下单时间是2020年11月11日 00:03:47,用户小皮下单时间是2020年11月11日 00:10:11,判断用户有没有成功参与秒杀活动。
public static void main(String[] args) throws ParseException {
//1.判断两位同学的下单时间是否在范围之内就可以了。
//2.要把每一个时间都换算成毫秒值。
String start = "2020年11月11日 0:0:0";
String end = "2020年11月11日 0:10:0";
String jia = "2020年11月11日 0:03:47";
String pi = "2020年11月11日 0:10:11";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
long startTime = sdf.parse(start).getTime();
long endTime = sdf.parse(end).getTime();
// System.out.println(startTime);
// System.out.println(endTime);
long jiaTime = sdf.parse(jia).getTime();
long piTime = sdf.parse(pi).getTime();
if(jiaTime >= startTime && jiaTime <= endTime){
System.out.println("小贾同学参加上了秒杀活动");
}else{
System.out.println("小贾同学没有参加上秒杀活动");
}
System.out.println("------------------------");
if(piTime >= startTime && piTime <= endTime){
System.out.println("小皮同学参加上了秒杀活动");
}else{
System.out.println("小皮同学没有参加上秒杀活动");
}
}
😵 面试题
请计算出2021年08月06日11点11分11秒,往后走2天14小时49分06秒的时间是多少
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Datedemo {
public static void main(String[] args) throws ParseException {
String s1 = "2021年08月06日 11时11分11秒";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
Date d1 = sdf.parse(s1);
System.out.println(d1); // Fri Aug 06 00:11:11 CST 2021
long l = d1.getTime() + (2 * 24 * 60 * 60 + 14 * 60 * 60 + 49 * 60 + 6) * 1000L;
String res = sdf.format(l);
System.out.println(res); // 2021年08月09日 02时00分17秒
}
}
6.3 Calendar类
Calendar
类代表了系统此刻日期对应额日历对象,Calendar
类是一个抽象类,不能直接创建对象
💗 Calendar
日历类创建日历对象的方法
😇 Calendar
的 常用方法
🙋举个栗子:
import java.util.Calendar;
import java.util.Date;
public class CalendarDemo {
public static void main(String[] args) {
// 获取系统此时的日历对象
Calendar cal = Calendar.getInstance();
System.out.println(cal); // 打印出日历中的所有字段以及字段值信息
// 获取日历的信息
int year = cal.get(Calendar.YEAR);
System.out.println(year); // 2023
int month = cal.get(Calendar.MONTH) + 1; // 月份从0开始计数
System.out.println(month); // 8(7+1=8)
// 修改日历的某个字段信息(一般不修改)
// cal.set(Calendar.YEAR, 1999);
// System.out.println(cal.get(Calendar.YEAR)); // 1999
// 为某个字段增加或减少制定的值
// 64天59分后是什么时间
cal.add(Calendar.DAY_OF_YEAR,64);
cal.add(Calendar.MINUTE,59);
// 拿到此时的日期对象
Date date = cal.getTime();
System.out.println(date); // 前面增加了时间,时间已经变了
// 拿到此刻的时间毫秒值
long timeInMillis = cal.getTimeInMillis();
System.out.println(timeInMillis);// // 前面增加了时间,时间已经变了
}
}
❗️注意:
Calendar
是可变日期对象,一旦修改后其对象本身表示的时间将产生变化
6.4 JDK8新增日期类
- 新增的 API 严格区分了时刻、本地日期、本地时间,并且,对日期和时间进行运算更加方便。
- 其次,新 API 的类型几乎全部是不变类型(和
String
的使用类似),可以放心使用不必担心被修改。
6.4.1 LocalDateTime
LocalDate
、 LocalTime
、LocalDateTime
- 它们 分别表示日期(年月日),时间(时分秒),日期时间(年月日时分秒)对象,他们的类的实例是不可变的对象。
- 它们三者构建对象和 API 都是通用的
💞 创建对象的 API
🙋举个栗子:
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 2022-11-27T20:35:04.898
LocalDateTime localDateTime = LocalDateTime.of(2020, 11, 11, 11, 11, 11);
System.out.println(localDateTime); // 2020-11-11T11:11:11
}
💃 获取信息的 API
🙋举个栗子:
public static void main(String[] args) {
LocalDateTime localDateTime = LocalDateTime.of(2020, 11, 11, 11, 11, 20);
int year = localDateTime.getYear();
System.out.println("年为" +year); // 年为2020
int month = localDateTime.getMonthValue();
System.out.println("月份为" + month); // 月份为11
Month month1 = localDateTime.getMonth();
System.out.println(month1); // 输出英文的月份:NOVEMBER
int day = localDateTime.getDayOfMonth();
System.out.println("日期为" + day); // 日期为11
int dayOfYear = localDateTime.getDayOfYear();
System.out.println("这是一年中的第" + dayOfYear + "天"); // 这是一年中的第316天
DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
// DayOfWeek dayOfWeek = localDateTime.getDayOfWeek().getValue(); // 3
System.out.println("星期为" + dayOfWeek); // 星期为WEDNESDAY
int minute = localDateTime.getMinute();
System.out.println("分钟为" + minute); // 分钟为11
int hour = localDateTime.getHour();
System.out.println("小时为" + hour); // 小时为11
}
🙉 LocalDateTime
转换 API
🙋举个栗子:
public static void main(String[] args) {
LocalDateTime localDateTime = LocalDateTime.of(2020, 12, 12, 8, 10, 12);
LocalDate localDate = localDateTime.toLocalDate();
System.out.println(localDate); // 2020-12-12
LocalTime localTime = localDateTime.toLocalTime();
System.out.println(localTime); // 08:10:12
}
☀️ 修改相关的 API
这些方法返回的是一个新的实例引用,因为 LocalDateTime
、 LocalDate
、 LocalTime
都是不可变的。
🙋举个栗子:
public static void main(String[] args) {
//public LocalDateTime plusYears (long years) 添加或者减去年
LocalDateTime localDateTime = LocalDateTime.of(2020, 11, 11, 13, 14, 15);
LocalDateTime newLocalDateTime = localDateTime.plusYears(1);
System.out.println(localDateTime); // 2020-11-11T13:14:15
System.out.println(newLocalDateTime); // 2021-11-11T13:14:15
LocalDateTime newLocalDateTime1 = localDateTime.plusYears(-1);
System.out.println(newLocalDateTime1); // 2019-11-11T13:14:15
LocalDateTime newLocalDateTime2 = localDateTime.withYear(2048);
System.out.println(newLocalDateTime2); // 2048-11-11T13:14:15
}
还有用于比较两个LocalDate
的方法:isBefore
、isAfter
🙋举个栗子:
import java.time.LocalDate;
import java.time.MonthDay;
public class Demo {
public static void main(String[] args) {
LocalDate myDate=LocalDate.of(2018,9,5);
LocalDate nowDate=LocalDate.now();
System.out.println("今天是2018年9月5号吗?"+nowDate.equals(myDate));
// 今天是2018年9月5号吗?false
System.out.println(myDate+"是否在"+nowDate+"之前?"+myDate.isBefore(nowDate));
// 2018-09-05是否在2023-08-13之前?true
System.out.println(myDate+"是否在"+nowDate+"之后?"+myDate.isAfter(nowDate));
// 2018-09-05是否在2023-08-13之后?false
System.out.println("------------------------------------");
// 判断今天是否是你的生日?
LocalDate birDate = LocalDate.of(2000,9,8);
LocalDate nowDate1=LocalDate.now();
MonthDay birMd = MonthDay.of(birDate.getMonthValue(), birDate.getDayOfMonth());
MonthDay nowMd = MonthDay.from(nowDate1); // 直接从日期对象中获取月、日
System.out.println("今天是你的生日吗"+birMd.equals(nowMd));
// 今天是你的生日吗false
}
}
6.4.2 Instant
JDK8 获取时间戳特别简单,且功能更丰富。
Instant
类由一个静态的工厂方法 now()
可以返回当前时间戳
时间戳是包含日期和时间的,与 java.util.Date
很类似,事实上 Instant
就是类似 JDK8 以前的 Date
。
Instant
和 Date
这两个类可以进行转换。
🙋举个栗子:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
public class InstantDemo {
public static void main(String[] args) {
// 得到一个世界标准时间的时间戳
Instant instant1 = Instant.now();
System.out.println(instant1); // 2023-08-13T09:41:29.346221200Z
// 我们在东八区
ZonedDateTime instant2 = instant1.atZone(ZoneId.systemDefault());
System.out.println(instant2); // 2023-08-13T17:41:29.346221200+08:00[Asia/Shanghai]
// Instant转为Date对象
Date date = Date.from(instant1);
// Date date = Date.from(instant2); 错误,必须是Instant转
System.out.println(date); // Sun Aug 13 17:41:29 CST 2023
// Date对象转为Instant
Instant i = date.toInstant();
System.out.println(i); // 2023-08-13T09:41:29.346Z
}
}
6.4.3 DateTimeFormatter
JDK8中,引入了一个全新的日期与时间格式器DateTimeFormatter
- 正反都能调用
format
方法
🙋举个栗子:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Demo {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println(now);// 2023-08-13T17:58:15.246281200
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");
// 用时间格式化格式化器
String res1 = now.format(pattern);
System.out.println(res1);//2023-08-13 17:58:15 周日 下午
// 用格式化器格式化时间
String res2 = pattern.format(now);
System.out.println(res2);//2023-08-13 17:58:15 周日 下午
// 解析字符串时间
DateTimeFormatter pattern2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String s="2022-09-07 22:23:46";
LocalDateTime res = LocalDateTime.parse(s, pattern2);
System.out.println(res); // 2022-09-07T22:23:46
}
}
6.4.4 Period/Duration
⚡️ Period
在JDK8中,我们可以使用 java.time.Period
计算 日期间隔 差异,用于LocalDate
之间的比较
🙋举个栗子:
public static void main(String[] args) {
LocalDate localDate1 = LocalDate.of(2020, 1, 1);
LocalDate localDate2 = LocalDate.of(2048, 12, 12);
Period period = Period.between(localDate1, localDate2);
System.out.println(period);//P28Y11M11D
System.out.println(period.getYears());//28
System.out.println(period.getMonths());//11
System.out.println(period.getDays());//11
System.out.println(period.toTotalMonths());//347
}
⚡️ Duration
在JDK8中,我们可以使用 java.time.Duration
计算 时间间隔 差异,用于LocalDateTime
之间的比较,也可以用于Instant
之间的比较。
🙋举个栗子:
public static void main(String[] args) {
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 1, 1, 13, 14, 15);
LocalDateTime localDateTime2 = LocalDateTime.of(2020, 1, 2, 11, 12, 13);
Duration duration = Duration.between(localDateTime1, localDateTime2);
System.out.println(duration);//PT21H57M58S
System.out.println(duration.toDays());//0
System.out.println(duration.toSeconds());//79078
System.out.println(duration.toMillis());//79078000
System.out.println(duration.toNanos());//79078000000000
}
6.4.5 ChronoUnit
ChronoUnit
类可用于在单个时间单位内测量一段时间,这个工具类是最全的了,可以用于比较所有的时间单位