目录
时间日期在计算机中的本质
时间日期类
一代、java.util.Date
二代、Calendar
三代、java.time包
Instant类
LocalDate类(当前操作系统的日期)
时间日期是每个程序都不可避免要操作到的数据类型。
在计算机中,时间是被看成一个时间轴。在这个时间轴上固定了一个时间点作为“时间原点”,然后计算机中存放的是当前时间距离这个时间原点过了多少毫秒。
所以,计算机中时间的本质存放的是一个整数,这个整数很大,所以用的是long类型来存放。
在System中有个方法,currentTimeMillis,可以获取到 当前时间 距离 时间原点 过了多少毫秒。
它主要用于两个地方:
其他场景,直接用JDK中先人写好的时间日期类来运算。
在Java里,时间日期类的设计经历了三代。(三代都在用)
java里有两个叫Date的类,一个是util包,一个是sql包(sql.Date 是 util.Date的子类)
它的大量方法和构造都过时了;因为 时间原点 发生了变化,现在的时间原点是“1970-1-1 00:00:00:000”,而Date类中算法是用“1900-1-1 00:00:00:000”,所以导致里面计算年月日时分秒的方法都会发生错误。
还在用Date的原因:
1.获取当前时间的Date对象是最简单的,直接new就可以了2.有个工具类,把毫秒数转成人能看懂的时间日期字符串,特别方便。---SimpleDateFormat(简单日期格式化)
3.在数据库操作中,默认仍然在使用java.sql.Date来表示时间日期,而这个类是java.util.Date的子类
常用API
1.new Date() 获取当前时间的Date对象;
2.用SimpleDateFormat工具类对Date对象进行文本格式化
3.getTime() 方法获取Date对象中存放的毫秒数;
public static String getDate(){
//获取当前时间
Date now = new Date().getTime;
//格式化时间日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E a HH:mm:ss");
String msg = sdf.format(now);
return msg;
}
由于Date的过时,导致Date没法实现根据指定的年月日时分秒获取时间对象,所以java需要定义新的时间日期类。
Java规划,希望这个类能够统一表现世界上所有的历法。
因而它设计了Calendar这个类为抽象类,然后用各个子类代表各种历法。jdk本身只提供一个子类,实现的是公历,叫做 “ GregorianCalendar ”
常用API
1、Calendar.getInstance()获取当前操作系统的日历对象。由于大家的操作系统都是中文版,用的都是公历,所以你们得到都是公历历法对象;
2、Calendar对象的4个set方法;
3、Caldenar对象的get方法,可以获取指定的某个日历字段。
【指定日期 用字符串显示】
转出Date,再SimpleDateFormat格式化
public class TestCalendar {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();//获取到的是当前的日历时间
//设置指定时间
cal.set(1949,10,1);//设置为指定年月日
cal.set(2008,5,12,2,12);//设置年月日时分
cal.set(2010,5,12,12,30,56);//设置年月日时分秒
cal.set(Calendar.YEAR,1997);//设置指定日历字段的值
cal.set(Calendar.DAY_OF_MONTH,15);
//获取某个日历字段的值
int year = cal.get(Calendar.YEAR);//获取某个日历字段的值
System.out.println(year);
int dayOfYear = cal.get(Calendar.DAY_OF_YEAR);
System.out.println(dayOfYear);
}
}
练习:
public class Test {
public static void main(String[] args) {
//输入一个人出生的年月日,获取他是星期几出生的
int year = 2023;
int month = 1;
int dayOfMonth = 8;
Calendar cal = Calendar.getInstance();
//外国月份从0月到12月 所以月份要-1
cal.set(year,month - 1,dayOfMonth);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
System.out.println(dayOfWeek);
//通过calendar 转换成一个 Date对象
Calendar calendar=Calendar.getInstance();//通过calendar 获取当前操作系统的日历对象
Date date=calendar.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("E");
System.out.println(sdf.format(date));//文本格式化
}
}
在新的java.time包中,时间的精度不再是毫秒,而是达到纳秒。long类型存不下这么大数据量了;
所以,专门设计了Instant类
Instant类中有两个属性:
1.long seconds(存放距离过了时间原点过了多少秒)2.int nanos (存放秒后的精度~纳秒)
同时,这两个属性都有final修饰,意味着这两个属性不可变。
一旦一个Instant对象产生以后,那么它代表的瞬时值就不会发生变化了,后面如果我们要做运算都不是在原对象上进行变化,而是会产生一个新的对象。
(瞬时类用的不多,很少操作到纳秒级)
public static void main(String[] args) {
long beign = System.currentTimeMillis();//获取当前计算机中存放的时间,它是毫秒数的整数
for(int i = 0; i < 1000; i++){
System.out.println("hello");
}
long end = System.currentTimeMillis();
System.out.println(end - beign);
}
1.获取当前日期时间,都是调用静态的now方法
2.获取指定的时间日期,都是调用静态的of方法
3.通过plusXxxx()方法,给当前时间日期对象增加时间日期值,Xxxx代表的就是添加的时间日期字段
4.通过minusXxxx()方法,给当前时间日期对象减少时间日期值
注意:增加减少后的结果都是产生一个新的LocalDate/LocalTime/LocalDateTime,不是在原对象上进行修改。理由与Instant一样,这些类里面的字段都是final的。
5.比较时间日期,需要用到两个类:(Period)(Duration);前者是指日期之间的差值,后者是时间上的差值。
6.格式化;由于SimpleDateFormat是线程不安全的,又只支持Date对象,所以设计了新的DateTimeFormatter。
LocalTime(当前操作系统的时间)
LocalDateTime(年月日 时分秒都有)
public class TestLocalDateTime {
public static void main(String[] args) {
//获取当前的时间日期对象
LocalDate nowDate = LocalDate.now();
LocalTime nowTime = LocalTime.now();
LocalDateTime nowDateTime = LocalDateTime.now();
System.out.println(nowDate.toString());
System.out.println(nowTime);
System.out.println(nowDateTime);
//获取指定的时间日期对象
LocalDate lastDate = LocalDate.of(1997,7,1);
LocalTime lastTime = LocalTime.of(9,0,0);
LocalDateTime lastDateTime = LocalDateTime.of(2022,5,20,8,1,30);
System.out.println(lastDate);
System.out.println(lastTime);
System.out.println(lastDateTime);
//增加时间日期
LocalDate newDate = nowDate.plusDays(5);//增加天数
newDate = nowDate.plusMonths(3);//增加月份
newDate = nowDate.plusYears(2);//增加年份
newDate = nowDate.plusWeeks(4);//增加星期
System.out.println(newDate);
//减少时间日期
LocalDateTime newDateTime = nowDateTime.minusDays(5)//减少天数
System.out.println(newDateTime);
//比较时间日期
//获取日期之间的差值(只支持LocalDate/LocalDateTime)
//用后面的日期 减去 前面的日期
Period betweenDate = Period.between(newDate,nowDate);
System.out.println(betweenDate.getDays());//获取差多少天
System.out.println(betweenDate.getYears());//差多少年
System.out.println(betweenDate.getMonths());//差多少月
//获取时间差值(支持LocalTime/LocalDateTime)
Duration betweenTime= Duration.between(nowTime,LocalTime.of(18,0));
System.out.println(betweenTime.getSeconds());
System.out.println(betweenTime.toHours());
System.out.println(betweenTime.toMinutes());
//格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern
("yyyy年MM月dd日 E HH:mm:ss");
String str = formatter.format(nowDateTime);
System.out.println(str);
}
}