一、JDK7的类
(1)Date 时间
(2)SimpleDateFormat 格式化时间
(3)Calendar 日历
格林尼治时间(Greenwich Mean Time),简称GMT。
目前的世界标准时间(UTC)以替换为原子钟(根据铯原子的振动频率计算)。
中国标准时间=世界标准时间+8小时。
时间单位换算:
1秒= 1000毫秒
1毫秒= 1000微妙
1微妙=1000纳秒
1.Date类
先介绍System类,System类是一个工具类,提供了一些与系统相关的方法。
System的currentTimeMillis()方法返回当前系统的时间毫秒值形式。计算机中的时间原点为1970年1月1日00:00:00.中国(东八区)的时间原点为1970年1月1日08:00:00.currentTimeMillis()方法的返回值是指从时间原点开始到现在经过的毫秒的值。
例如,输出当前时间与时间原点之间的经过的毫秒值:
再例如,比较不同判断质数的方法执行的时间:
public class Test2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
int number1 = 0;
for (int i = 0; i < 10000; i++) {
boolean flag = isPrime1(i);
if(flag){
number1++;
}
}
long end = System.currentTimeMillis();
System.out.println("isPrime1()运行时间为"+(end-start)+"毫秒");
long start2 = System.currentTimeMillis();
int number2 = 0;
for (int i = 0; i < 10000; i++) {
boolean flag = isPrime2(i);
if(flag){
number2++;
}
}
long end2 = System.currentTimeMillis();
System.out.println("isPrime2()运行时间为"+(end2-start2)+"毫秒");
}
public static boolean isPrime1(int number){
for (int i = 2; i < number; i++) {
if(number%i == 0){
return false;
}
}
return true;
}
public static boolean isPrime2(int number){
for (int i = 2; i <= Math.sqrt(number); i++) {
if(number%i == 0){
return false;
}
}
return true;
}
}
运行结果如下:
接着介绍Date类,Date类也是通过毫秒值计算时间,Date类用来描述时间,精确到毫秒。利用空参构造创建的对象,默认表示系统当前时间;利用有参构造创建的对象,表示指定的时间。查看Date类的源码:
例如:
输出的不是毫秒值,那时因为Date类重写了toString()方法:
再例如,利用有参构造获取时间原点:
再例如,使用setTime()方法修改时间,参数为long类型,作用等同于有参构造方法:
再例如,使用getTime()获取Date对象记录的时间的毫秒值:
2.SimpleDateFormat
Date类只能按照默认的格式进行打印(重写的toString())。
构造方法:
成员方法:
有参构造的pattern:
例子:
例如,默认格式与多种自定义格式:
public class Test2 {
public static void main(String[] args) {
//1.利用空参构造创建SimpleDateFormat对象,默认格式
SimpleDateFormat sdf1 = new SimpleDateFormat();
Date d1 = new Date(0L);
String str1 = sdf1.format(d1);
System.out.println(str1);
//2.利用带参构造创建SimpleDateFormat对象,指定格式
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str2 = sdf2.format(d1);
System.out.println(str2);
// 3.利用带参构造创建SimpleDateFormat对象,指定格式,使用E显示星期
SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss E");
String str3 = sdf3.format(d1);
System.out.println(str3);
}
}
运行结果如下:
再例如,parse()方法解析字符串生成Date对象:
注意:使用有参构造创建SimpleDateFormat对象中的模式要与字符串中的模式一致。
3.Calendar
Calendar代表了系统当前时间的日历对象,可以单独修改、获取时间中的年月日,避免了使用毫秒值计算的麻烦。
细节:Calendar是一个抽象类,不能直接创建对象。获取Calendar日历类对象的方法:
Calendar.getInstance()获取日历对象,底层是根据系统的不同时区来获取不同的日历对象会把时间中的纪元,年,月,日,时,分秒,星期等等都放到一个数组当中。细节:
(1)数组中的月份范围为0~11,如果取出来的是0,那么实际上是1月。
(2)星期的范围为1~7,1表示星期日,2表示星期一,以此类推。
例如:
再例:
public class Test2 {
public static void main(String[] args) throws ParseException {
//1.获取日历对象,底层是根据系统的不同时区来获取不同的日历对象
//会把时间中的纪元,年,月,日,时,分秒,星期等等都放到一个数组当中
Calendar c = Calendar.getInstance();
System.out.println(c);
//2.修改日历代表的时间
Date d = new Date(0L);
c.setTime(d);
System.out.println(d);
//根据get()方法获取Calendar底层数组中保存的不同值
//0表示纪元,1表示年,2表示月,3表示一年中的第几周,4表示一个月中的第几周,5表示一个月中的第几天(日期)
int year = c.get(1);//也可以写成int year = c.get(Calendar.YEAR);
int month = c.get(2)+1;//月份要加1
int date = c.get(5);
System.out.println(year+","+month+","+date);
//set修改数组中的某一个字段
c.set(Calendar.YEAR,2000);//把年份改为2000年
System.out.println(c);
//add修改某字段加或减
c.add(Calendar.YEAR, 1);//年份加一
System.out.println(c);
c.add(Calendar.YEAR, -2);//年份减二
System.out.println(c);
}
}
运行结果:
二、JDK8的类
JDK8新增的时间相关类相对于JDK7来说具有两个层面的好处。
(1)代码层面:JDK7代码写起来比较麻烦,JDK8代码写起来比较简单;
(2)安全层面:JDK7的时间相关类在多线程环境下可能会导致数据安全的问题,例如多个线程修改同一个时间类对象。JDK8解决了这一问题,JDK8的时间日期对象都是不可变的,如果想修改时间,原来对象的时间不会改变,而是返回一个新的对象。
JDK7的时间相关类需要学习是因为在一些老的项目中使用了,而现在的项目都是用JDK8的时间相关类。
JDK8的时间相关类:
注意上图中的横线上的类是JDK7的类,上图展示了JDK7的时间相关类与JDK8的时间相关类之间的关系。
1.ZoneId时区
Java定义时区的格式是“洲名/城市名”或“国家名/城市名”。
例如:
public class Test2 {
public static void main(String[] args) throws ParseException {
//1.获取所有时区
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
System.out.println(zoneIds.size());
System.out.println(zoneIds);
//2.获取当前系统的默认时区Asia/shanghai
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);
//3.获取指定的时区,字符串属于所有时区中的一个
ZoneId zoneId1= ZoneId.of("Asia/Pontianak");
System.out.println(zoneId1);
}
}
运行结果如下:
2.Instant时间戳
说明:上图中的标准时间是指格林尼治的时间,比中国晚8小时。
public class Test2 {
public static void main(String[] args) throws ParseException {
//1.获取当前时间的Instance对象(标准时间)
System.out.println("1============");
Instant now = Instant.now();
System.out.println(now);
System.out.println("2============");
//2.根据(秒/毫秒/纳秒)获取Instance对象
Instant instant1= Instant.ofEpochMilli(0L);//根据毫秒获取对象
System.out.println(instant1);
Instant instant2 = Instant.ofEpochSecond(1L);//根据秒获取对象
System.out.println(instant2);
Instant instant3 = Instant.ofEpochSecond(1L,1000000000L);//根据秒加上纳秒获取对象,1秒+1000 000 000秒等于2秒
System.out.println(instant3);
//3.指定获取指定时区的时间
System.out.println("3============");
ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(time);
System.out.println("4============");
//4.判断两个时间的先后
Instant instant4 = Instant.ofEpochMilli(0L);
Instant instant5 = Instant.ofEpochMilli(1000L);
boolean result1 = instant4.isBefore(instant5);//判断instant4代表的时间是否在instant5之前
System.out.println(result1);
System.out.println(instant4.isAfter(instant5));
System.out.println("4============");
//增减时间,注意JDK8增减时间原时间类对象不变,增减的结果为函数返回值
Instant instant6= Instant.ofEpochMilli(3000L);
System.out.println(instant6);
Instant instant7 = instant6.minusMillis(1);//减一秒
}
}
运行结果:
3.ZonedDateTime带时区的时间
public class Test2 {
public static void main(String[] args) throws ParseException {
System.out.println("1=========");
//1.获取当前时间对象(带时区)
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);
System.out.println("2=========");
//2.获取指定的时间对象(带时区)
//年月日时分秒的方式指定
ZonedDateTime time1 = ZonedDateTime.of(2023,10,1,11,12,12,0,ZoneId.of("Asia/Shanghai"));
System.out.println(time1);
System.out.println("3=========");
//3.withxxx修改时间系列的方法
ZonedDateTime time3 = time1.withYear(2000);
System.out.println(time3);
System.out.println("4=========");
//4.减少时间
ZonedDateTime time4 = time1.minusYears(2000);
System.out.println(time4);
System.out.println("5=========");
//5.增加时间
ZonedDateTime time5 = time1.plusYears(2000);
System.out.println(time5);
}
}
运行结果:
4.DateTimeFormatter日期格式化类
成员方法:
public class Test2 {
public static void main(String[] args) throws ParseException {
//获取时间对象
ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
//解析/格式化器
DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss E a");
//格式化
System.out.println(dtf1.format(time));
}
}
运行结果:
5.LocalDate、LacalTime、LocalDateTime
三者之间进行转化的方法: