1.常用类-Date(日期类)
1.概述
1.日期类继承结构
1.java.until.Date是日期类
2.DateFromat是日期格式类、SimpleDateFormat是日期格式类的子类Timezone代表时区
3.Calendar是日历类,GregorianCalendar是日历的子类
2.常用的日期相关类-Date
1.Date构造方法
Date是日期类,Date的构造方法如下:
Date(long date)使用给定的毫秒时间价值构建Date对象
Date()返回系统的当前时间
日期是有时间起点的,以地理位置格林尼治时间1970-01-01 00:00:00 为标准,视为时间的起点;Date(long date)指的是距离标准时间过了多少毫秒;
public class Test01 {
@Test
public void DateConstructorTest(){
//创建日期对象,返回系统的当前时间
Date date = new Date();
System.out.println(date);
//创建距离格林尼治时间标准时间过了1000毫秒的日期
Date date2 = new Date(1000L);
System.out.println(date2);
}
}
2.Date类常用方法
/**
* Date日期类
*/
public class Test01 {
public static void main(String[] args) throws ParseException {
//1) 创建Date对象返回当前时间
Date date = new Date();
System.out.println( date ); //Sat Aug 14 16:01:09 CST 2021, CST表示中国标准时间
//2) 获得Date时间距离1970-1-1 00:00:00 经过的毫秒数
long time = date.getTime();
System.out.println( time ); //1628928069456
//3) 调用System.currentTimeMillis()返回当前时间对应的毫秒数
long currentTimeMillis = System.currentTimeMillis();
System.out.println( currentTimeMillis ); //1628928069469
//4) 根据毫秒数创建日期对象
Date date2 = new Date(currentTimeMillis);
System.out.println( date2 ); //Sat Aug 14 16:01:09 CST 2021
}
}
3.常用的日期相关类-java.util.SimpleDateFormat
SimpleDateFormat是日期格式类,它可以按照指定的格式将date对象格式为字符串;也可以按照指定的格式将字符串解析为Date
1.format方法
//5) 使用SimpleDateFormat可以对Date日期格式化
//创建SimpleDateFormat对象, 通过构造方法指定模式串,常用的格式符: y年, M月, d日, H小时, m分钟, s秒
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//调用SimpleDateFormat对象的format( Date)可以把日期转换为字符串
String s = sdf.format(date);
System.out.println( s );//2021-08-14 16:07:07
2.parse方法
//6) 把表示日期的字符串转换为Date日期对象
String text = "2086年5月16日 8:28:58";
//根据字符串格式创建SimpleDateFormat对象
SimpleDateFormat another = new SimpleDateFormat("yyyy年M月dd日 H:mm:ss");
//调用SimpleDateFormat对象的parse(String)可以把字符串解析为Date对象, 该方法有检查异常需要预处理,当前选择抛出处理, 程序运行后,如果这一行产生了异常,说明another对象的格式符与text字符串不匹配
Date date3 = another.parse(text);
System.out.println( date3 );
4.常用类的日期相关类-java.util.Calender
Calender是日历类,主要用于设置日历时间,获取日历时间等操作;日历类是一个抽象类,它提供两种方式创建实例;如下所示:
1.创建Calender日历对象
public class Test01 {
@Test
public void CalendarTest(){
//获取实例对象:静态方法,推荐
Calendar calendar = Calendar.getInstance();
}
}
2.设置日历时间与获取日历时间
public class Test01 {
@Test
public void CalendarTest2(){
//1.创建对象
Calendar calendar = Calendar.getInstance();
//2.set方法设置日历信息 以 年月日时分秒
//设置年
calendar.set(Calendar.YEAR,2019);
//日历用0-11 表示 1-12月
calendar.set(Calendar.MONTH,1);
//设置日 一月中的天数
calendar.set(Calendar.DAY_OF_MONTH,8);
//设置一天中的小时数
calendar.set(Calendar.HOUR_OF_DAY,15);
//设置一小时的分钟数
calendar.set(Calendar.MINUTE,20);
//设置一分钟的秒数
calendar.set(Calendar.SECOND,58);
calendar.set(2018,1,2);
calendar.set(2017,1,2,22,20,20);
//3.get方法获取日历信息
System.out.println(calendar.get(Calendar.YEAR));
//日历用0-11 表示 1-12月
System.out.println(calendar.get(Calendar.MONTH));
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
System.out.println(calendar.get(Calendar.MINUTE));
System.out.println(calendar.get(Calendar.SECOND));
//4.将日历转为日期
Date date = calendar.getTime();
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
//5.将日期转为日历
Calendar calendar1 = Calendar.getInstance();
// 打印日历信息
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar1.getTime()));
}
}
5.总结
日期按照指定格式格式字符串,解析字符串到日期
日历操作。日历转日期操作
2.常用类-新日期类
1.传统日期类的弊端
1.弊端一
传统的日期类Date和Calendar中存在着大量的过时方法如下;
2.弊端二
日期计算复杂
存在线程安全问题
像日期和时间这样的类应该是不可变的,但Date和Calendar日期是可变的。不能处理闰秒的问题。
演示传统日期计算复杂问题
public class TestRegex03 {
/**
* 计算当前时间距离2012年 12月12日过了多少天
* */
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date d1=sdf.parse("2013-8-21");
Date d2 = new Date();
System.out.println(daysBetween(d1,d2));
System.out.println(daysBetween("2013-8-21","2023-8-21"));
}
public static int daysBetween(Date smdate,Date bdate) throws ParseException {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
smdate=sdf.parse(sdf.format(smdate));
bdate=sdf.parse(sdf.format(bdate));
Calendar cal = Calendar.getInstance();
cal.setTime(smdate);
long time1 = cal.getTimeInMillis();
cal.setTime(bdate);
long time2 = cal.getTimeInMillis();
long between_days=(time2-time1)/(1000*3600*24);
return Integer.parseInt(String.valueOf(between_days));
}
public static int daysBetween(String smdate,String bdate) throws ParseException{
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(smdate));
long time1 = cal.getTimeInMillis();
cal.setTime(sdf.parse(bdate));
long time2 = cal.getTimeInMillis();
long between_days=(time2-time1)/(1000*3600*24);
return Integer.parseInt(String.valueOf(between_days));
}
}
2.演示传统日期线程安全问题
public class TestRegex03 {
public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/*程序入口*/
public static void main(String[] args) {
for (int i = 1; i <=10; i++) {
new Thread(){
@Override
public void run() {
try {
System.out.println(simpleDateFormat.parse("2012-12-12 12:12:12"));
} catch (ParseException e) {
e.printStackTrace();
}
}
}.start();
}
}
}
2.新增日期类使用
1.日期初始化操作
1.通过now方法获得日期实例
Date-Time API中的所有类均生成不可变对象,它们线程安全的,并且这些类不提供公共的构造函数,无法通过new的方式来创建对象;它提供静态方法now获取当前系统时间的实例;
1.通过now方法获得日期实例
public class TestRegex05 {
public static void main(String[] args) {
//获得Instant实例对象,获得是格林尼治的当前时间
Instant instant = Instant.now();
System.out.println(instant);
//获得LocalDate实例,获得本地的当前年、月、日
LocalDate localDate = LocalDate.now();
System.out.println(localDate);
//获得LocalTime实例,获得本地的当前时、分、秒
LocalTime localTime = LocalTime.now();
System.out.println(localTime);
//获得LocalDateTime实例,获得本地的当前年、月、日、时、分、秒
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
//使用now方法创建ZonedDateTime实例,获得本地时区的年、月、日、时、分、秒
ZonedDateTime zonedDateTime = ZonedDateTime.now();//我国时间以东8区为准,也就是所说的北京时间。按东8区计算
System.out.println(zonedDateTime);
}
}
Date-Time API 中除了通过now方法获得日期和时间外,还能获得具体的年、月、日;示例如下
2.获得当前的年、月、日
public class TestRegex03 {
@Test
public void nowMethodTest2(){
Year year = Year.now();
System.out.println(year);
YearMonth month = YearMonth.now();
System.out.println(month);
MonthDay day = MonthDay.now();
System.out.println(day);
}
}
3.通过of方法获得日期实例
除此之外,通过静态方法of可以根据给定的参数生成对应的日期/时间对象,基本上每个类都有of方法生成对应的类;
public class TestRegex03 {
@Test
public void ofMethodTest3() {
//根据参数创建本地日期对象
LocalDate date = LocalDate.of(2012, 12, 1);
System.out.println(date);
//根据参数创建本地时间对象
LocalTime localTime = LocalTime.of(9,12,12,311);
System.out.println(localTime);
//根据参数创建本地日期加时间对象
LocalDateTime localDateTime = LocalDateTime.of(2012,12,12,12,12,12);
System.out.println(localDateTime);
//根据日期和时间创建本地日期时间对象
LocalDateTime localDateTime1 = LocalDateTime.of(date,localTime);
System.out.println(localDateTime1);
}
}
2.获得具有时区的日期实例
在学习ZonedDateTime的时候,发现这个对象里面封装的不仅仅有日期时间,并且还有偏移量+时区;在java中,可以通过一个类ZoneId的getAvailableZoneIds方法可以获得一个Set集合,集合中封装了600个时区。
1.时区相关操作
public class TestRegex03 {
@Test
public void ZoneIdMethodTest1() {
//获取所有时区信息
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
for(String zone: availableZoneIds){
System.out.println(zone);
}
//获得系统默认时区
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);
}
}
2.为LocalDateTime封装时区操作
public class TestRegex03 {
@Test
public void ZoneIdMethodTest2() {
//1.封装LocalDateTime对象,
LocalDateTime localDateTime = LocalDateTime.of(2012,12,12,23,8,8);
//2.为localDateTime封装时区
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime);
//3.更改时区查看其他时区的当前时间,通过withZoneSameInstant()
ZonedDateTime zonedDateTime1 = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime1);
}
}