Date
Date类的实例封装了一个long类型的时间戳,即从1970年1月1日起的毫秒数。
Date类提供的主要功能是,与时间戳相互转换、与其它Date实例相比较、获取系统当前的日期。
Date类没有提供修改
获取系统当前日期
// 空参构造函数会获取当前系统时间戳,用以初始化Date实例
Date date = new Date();
// Sun Dec 10 19:47:45 CST 2023
System.out.println(date);
与时间戳相互转换
Date date1 = new Date();
// 获取date1封装的时间戳
long timeStamp = date1.getTime();
// 用date1的时间戳实例化date2
Date date2 = new Date(timeStamp);
Date date3 = new Date();
// 可以设置Date实例的时间戳
date3.setTime(timeStamp);
// 打印true
System.out.println(date1.equals(date2));
// 打印true
System.out.println(date1.equals(date3));
与其它Date实例相比较
Date date1 = new Date();
Thread.sleep(100L);
Date date2 = new Date();
// 由于date1的时间戳比date2小,打印-1
System.out.println(date1.compareTo(date2));
// 打印true
System.out.println(date1.before(date2));
// 打印true
System.out.println(date2.after(date1));
// 打印false
System.out.println(date1.equals(date2));
DateFormat
负责将Date实例与日期字符串相互转换
Date实例转换为字符串
Date date = new Date();
DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒");
String dateStr = dateFormat.format(date);
// 2023年12月10日 07时57分45秒
System.out.println(dateStr);
字符串转化为Date实例
DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒");
try {
Date date = dateFormat.parse("2023年12月10日 07时57分45秒");
// 打印Sun Dec 10 07:57:45 CST 2023
System.out.println(date);
} catch (ParseException e) {
System.out.println("字符串无法转化为Date实例");
throw new RuntimeException(e);
}
日期和时间的格式化编码
Calendar
相比于Date,提供了针对年月日时分秒的设置和加法
主要功能:获得当前系统时间、与时间戳相互转换、与Date相互转换、设置年月日时分秒、增加年月日时分秒、获得年月日时分秒
获取系统当前时间
Calendar calendar = Calendar.getInstance();
// 打印java.util.GregorianCalendar[time=1702210801459,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2023,MONTH=11,WEEK_OF_YEAR=50,WEEK_OF_MONTH=3,DAY_OF_MONTH=10,DAY_OF_YEAR=344,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=8,HOUR_OF_DAY=20,MINUTE=20,SECOND=1,MILLISECOND=459,ZONE_OFFSET=28800000,DST_OFFSET=0]
System.out.println(calendar);
与时间戳相互转换
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
long timeStamp = calendar.getTimeInMillis();
与Date相互转换
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
calendar.setTime(date);
设置、增加、获得年月日时分秒
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2024);
calendar.add(Calendar.YEAR,1);
// 获得年份
int year = calendar.get(Calendar.YEAR);
// 获得月份
int month = calendar.get(Calendar.MONTH) + 1;
// 获得日期
int date = calendar.get(Calendar.DATE);
// 获得小时
int hour = calendar.get(Calendar.HOUR_OF_DAY);
// 获得分钟
int minute = calendar.get(Calendar.MINUTE);
// 获得秒
int second = calendar.get(Calendar.SECOND);
Java8的新时间日期 API
Java的旧版的日期时间API存在诸多问题,其中有:
- 非线程安全:java.util.Date 是非线程安全的,Java旧日期类是可变的。
- 结构定义混乱:java.util、java.sql中都有一个Date类,而格式化日期的类定义在java.text里。
- 时区处理麻烦:旧的日期类不提供国际化,没有时区支持。
java.time包下的LocalTime类、LocalDate类、LocalDateTime类中的方法
LocalDate/LocalTime 和 LocalDateTime 类用在不考虑时区的情况,默认是本地时区,即使用运行程序的计算机所设置的时区。它们不包含时区信息,因此不会考虑跨时区的问题。
@Test
public void testJava8Time(){
// 获得当前日期时间
LocalDateTime now = LocalDateTime.now();
// 可以获得年月日时分秒等等
int year = now.getYear();
int dayOfMonth = now.getDayOfMonth();
// 返回一个新的日期时间实例,它具有指定的年月日时分秒
// LocalDateTime是不可变类,withXXX方法、plusXXX、minusXXX会返回一个新实例
LocalDateTime newYear = now.withYear(2024);
LocalDateTime newMonth = newYear.withMonth(1);
LocalDateTime localDateTime = now.plusYears(2);
LocalDateTime localDateTime1 = now.plusWeeks(3);
LocalDateTime localDateTime2 = now.minusDays(4);
LocalDateTime localDateTime3 = now.minusMinutes(10);
// 可以指定年月日时分秒,并返回一个实例
LocalDateTime time = LocalDateTime.of(2023, 12, 30, 10, 45, 30);
// 日期时间转换为日期
LocalDate localDate = now.toLocalDate();
// 日期类、时间类提供的方法与日期时间类
LocalDate newDate = localDate.withMonth(5);
LocalDate.of(2024, 1, 1);
// 解析字符串
LocalTime time1 = LocalTime.parse("20:15:30");
}
4.2. Instant类
@Test
public void testInstant(){
Instant now = Instant.now();
// 中国在东八区,所以要比标准的时间偏移8个小时才能算出中国的时间
OffsetDateTime offsetDateTime = now.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime); // 打印2024-02-02T16:30:34.581194200+08:00
}
@Test
public void testInstant(){
Instant now = Instant.now();
System.out.println(now);
// 其实等效于System.currentTimeMillis(); 都是获得自1970年1月1日0时0分0秒(UTC)开始的毫秒数
long epochMilli = now.toEpochMilli();
// 自1970年1月1日0时0分0秒(UTC)开始的毫秒数可以转化为Instant实例
Instant instant = Instant.ofEpochMilli(epochMilli);
System.out.println(instant);
}
4.3. DateTimeFormatter类
@Test
public void testDateTimeFormatter(){
// DateTimeFormatter可以将LocalDateTime、LocalDate、LocalTime转化为字符串,这称为格式化format
// 也可以将字符串转化为LocalDateTime、LocalDate、LocalTime,这称为解析parse
// 下面这行代码创建了一个DateTimeFormatter,其格式化风格为LONG,即格式化出来的字符串较长,时区为系统时区ZoneId.systemDefault()
// 用这个DateTimeFormatter去格式化一个LocalDateTime、LocalDate、LocalTime,就可以得到一个本地化的较长的日期字符串
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withZone(ZoneId.systemDefault());
String str = dateTimeFormatter.format(LocalDateTime.now());
System.out.println(str);// 打印 2024年2月2日 CST 下午6:22:10
// 类似上面例子,只不过格式化风格为MEDIUM
DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withZone(ZoneId.systemDefault());
String str2 = dateTimeFormatter2.format(LocalDateTime.now());
System.out.println(str2);// 打印 2024年2月2日 下午6:22:10
// 类似上面例子,只不过格式化风格为FULL
DateTimeFormatter dateTimeFormatter3 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withZone(ZoneId.systemDefault());
String str3 = dateTimeFormatter3.format(LocalDateTime.now());
System.out.println(str3);// 打印 2024年2月2日星期五 中国标准时间 下午6:22:10
}
@Test
public void testDateTimeFormatter(){
// 预定义好的标准DateTimeFormatter
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_DATE_TIME;
LocalDateTime now = LocalDateTime.now();
String str = dateTimeFormatter.format(now);
System.out.println(str); //打印 2024-02-02T18:24:16.1728451
System.out.println(now); //打印 2024-02-02T18:24:16.172845100
}
@Test
public void testDateTimeFormatter(){
// 自定义的DateTimeFormatter
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
// 格式化LocalDateTime为字符串
String format = dateTimeFormatter.format(LocalDateTime.now());
System.out.println(format); // 打印2024年02月02日 18时29分20秒
// 解析时间字符串
TemporalAccessor parse = dateTimeFormatter.parse("2024年02月02日 18时26分52秒");
System.out.println(parse); // 打印{},ISO resolved to 2024-02-02T18:26:52
}