目录
时间日期是每个程序都不可避免要操作到的数据类型
时间日期在计算机中的本质
在计算机中,时间是被看成一个时间轴。在这个时间轴上固定了一个时间点作为“时间原点”,然后计算机中存放的是当前时间距离这个时间原点过了多少毫秒。
所以,计算机中时间的本质存放的是一个整数,这个整数很大,所以用的是long类型来存放。
在System中有个方法,currentTimeMillis,可以获取到 当前时间 距离 时间原点 过了多少毫秒。
它主要用于两个地方:
- 我们可以用这个方法获取到某段代码的执行时长,简单的判定执行效率;
- 如果我们需要进行唯一性命名的时候,可以直接使用这个方法用获取到的毫秒数来进行命名。
long startTime = System.currentTimeMillis();
// 执行操作...
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println("程序运行时间:" + elapsedTime + "毫秒");
时间日期类
其他场景,直接用JDK中先人写好的时间日期类来运算;在Java里,时间日期类的设计经历了三代(三代都在用)
java.util.Date
【一代】
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就完事儿了~
Date now = new Date();
2.它有个工具类,能把毫秒数转换成我们可以看懂的时间日期字符串---SimpleDateFormat(简单日期格式化)
3.在数据库操作中,默认仍然在使用java.sql.Date来表示时间日期,而这个类是java.util.Date的子类
public static String getDate(){
//获取当前时间,getTime方法获取Date对象中存放的毫秒数
Date now = new Date().getTime;
//格式化时间日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E a HH:mm:ss");
String msg = sdf.format(now);
return msg;
}
Calendar
【二代】
由于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包
【三代】
Instant类
在新的java.time包中,时间的精度不再是毫秒,而是达到纳秒。long类型存不下这么大数据量了;所以,专门设计了Instant类,它有两个属性:
- long seconds(存放距离过了时间原点过了多少秒)
- 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);
}
LocalDate类
获取当前日期时间,都是调用静态的now方法
//获取当前日期,不包含时间信息
LocalDate nowDate = LocalDate.now();
//获取当前时间,不包含日期信息
LocalTime nowTime = LocalTime.now();
//获取当前日期和时间
LocalDateTime nowDateTime = LocalDateTime.now();
获取指定时间日期,都是调用静态的of方法
//获取指定的时间日期对象
LocalDate lastDate = LocalDate.of(1997,7,1);
LocalTime lastTime = LocalTime.of(9,0,0);
LocalDateTime lastDateTime = LocalDateTime.of(2022,5,20,8,1,30);
通过plusXxx()方法,给当前时间日期对象增加时间日期值,Xxx代表的就是添加的时间日期字段
//增加时间日期
LocalDate newDate = nowDate.plusDays(5);//增加天数
newDate = nowDate.plusMonths(3);//增加月份
newDate = nowDate.plusYears(2);//增加年份
newDate = nowDate.plusWeeks(4);//增加星期
通过minusXxxx()方法,给当前时间日期对象减少时间日期值
//减少时间日期
LocalDateTime newDateTime = nowDateTime.minusDays(5)//减少天数
注意:增加减少后的结果都是产生一个新的LocalDate/LocalTime/LocalDateTime,不是在原对象上进行修改。理由与Instant一样,这些类里面的字段都是final的。
比较时间日期,需要用到两个类:(Period)(Duration);前者是指日期之间的差值,后者是时间上的差值
//获取日期之间的差值(只支持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());
格式化;由于SimpleDateFormat是线程不安全的,又只支持Date对象,所以设计了新的DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 E HH:mm:ss");
String str = formatter.format(nowDateTime);
System.out.println(str);
字符串转时间日期类 LocalDate.parse
LocalDate date = LocalDate.parse("2022-01-01");