1. Java8之前的日期处理
1.1 介绍
Java8之前使用的日期类是java.util.Date,这个类虽然有6个构造方法,但是很多都已过时,现在还保留的就是两个,一个是Date(),还有一个是Date(long date)。
接下来看一下这两个构造方法的使用
public class DateTest01 {
public static void main(String[] args) {
//Date()
Date d1 = new Date();
System.out.println(d1); // Mon Mar 31 19:12:29 CST 2025
/**
* Date(long date)
* 这里的date是距离1970-01-01 00:00:00的毫秒数
* 这里的结果是08:01:00的原因是我们在东八区,所以加上了时差8h
*/
Date d2 = new Date(1000 * 60);
System.out.println(d2); // Thu Jan 01 08:01:00 CST 1970
}
}
1.2 日期格式化
通过上面的例子,我们可以看到输出的时间不是我们所熟悉的时间格式,在不同环境的使用中,对于日期的格式要求也不一样,因此Java也为我们提供了日期格式化的工具。这个工具就是java.text包下的DateFormat。这个包下的子类SimpleDateFormat,就是我们需要的。进入这个类的帮助文档之后,就可以看到已经给了我们一个表格,通过这个表格我们就可以指定所需要的日期格式。
下面是这个类使用的示例:
public class DateTest01 {
public static void main(String[] args) throws ParseException {
Date date = new Date();
System.out.println(date); // Mon Mar 31 19:25:56 CST 2025
/**
* new SimpleDateFormat()
* 在使用时我们先创建一个SimpleDateFormat()对象,然后传入我们需要的时间格式即可
* 然后调用这个对象的format方法,就可以将日期格式化为我们想要的格式
*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String s1 = sdf.format(date);
System.out.println(s1); //2025-03-31 19:25:56
/**
* 除此之外,还有一个parse方法,可以将指定格式的日期还原为原先的格式
* 这里需要注意一点的是parse方法
* public Date parse(String source) throws ParseException
* 会抛出一个异常,当我们的日期格式和sdf中的格式不一样时,就会出现这个异常
*/
Date s2 = sdf.parse(s1);
System.out.println(s2); // Mon Mar 31 19:25:56 CST 2025
}
}
1.3 日历类
Java还给我们提供了一个类java.util.Calendar,这个类是专门用来处理日历的。
这是一个受保护的方法,因此不能new,如果想要获取日历对象,那么需要调用静态方法。所以日历类的使用实例如下:
Calendar calendar = Calendar.getInstance();
System.out.println(calendar); // java.util.GregorianCalendar[time=1743420649778...]
这是个很长的结果,因此我就直接省略了中括号里的内容,做个展示。我们日常用日历主要就是为了看年月日等相关信息,因此当我们得到了日历对象之后,通过调用get()方法,然后里面传入我们想要的信息,就可以获取到了。使用示例如下:
public class DateTest01 {
public static void main(String[] args) throws ParseException {
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
System.out.println(year); // 2025
//这里需要注意一点的是月份范围是0-11,0代表1月份,因此这里的2就是3月份
int month = calendar.get(Calendar.MONTH);
System.out.println(month); // 2
int day = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(day); // 31
int hour = calendar.get(Calendar.HOUR_OF_DAY);
System.out.println(hour); // 19
int min = calendar.get(Calendar.MINUTE);
System.out.println(min); // 39
int sec = calendar.get(Calendar.SECOND);
System.out.println(sec); // 57
}
}
除此之外,日历类中还有几个常用的方法需要了解一下。
方法 | 描述 |
---|---|
set(int field, int value) | 将给定的日历字段设置为给定的值 |
set(int year, int month, int date) | 设置日历的年月日 |
add(int field, int amount) | 给指定的参数加上一个值 |
setTime(Date date) | 让日历设置关联具体的时间 |
getTime() | 获取日历的具体时间 |
这里我写几个示例演示一下这些方法的使用:
public class DateTest01 {
public static void main(String[] args) throws ParseException {
Calendar calendar = Calendar.getInstance();
printCalendar(calendar); // 2025年3月31日
/**
* set(int field, int value)
* 第一个参数是需要修改的信息,例如我这里想要修改年,就直接设置为Calendar.YEAR
* 第二个参数是修改后的值,例如我这里要修改年份为2024
*/
calendar.set(Calendar.YEAR, 2024);
int year = calendar.get(Calendar.YEAR);
printCalendar(calendar); // 2024年3月31日
/**
* set(int year, int month, int date)
* 第一个参数为需要设置的年份的值
* 第二个参数为需要设置的月的值
* 第三个参数为需要设置的日的值
*/
calendar.set(2024, Calendar.AUGUST, 31);
printCalendar(calendar); // 2024年8月31日
/**
* add(int field, int amount)
* 第一个参数就是需要修改的信息
* 第二个参数就是想要在此基础上修改的值,这个值可正可负
*/
calendar.add(Calendar.YEAR, 2);
printCalendar(calendar); // 2026年8月31日
/**
* setTime(Date date)
* 这里就可以用new Date(),将日历关联到具体的时间
*/
calendar.setTime(new Date());
printCalendar(calendar); //2025年3月31日
/**
* getTime(): 获取日历的具体时间
*/
Date time = calendar.getTime();
System.out.println(time); // Mon Mar 31 20:21:40 CST 2025
}
public static void printCalendar(Calendar calendar) {
System.out.println(calendar.get(Calendar.YEAR) + "年" +
(calendar.get(Calendar.MONTH) + 1) + "月" +
calendar.get(Calendar.DAY_OF_MONTH) + "日");
}
}
2. Java8之后的日期处理
2.1 介绍
原先的日期API存在线程安全问题,在单线程的情况下不会出现什么问题,但是在高并发的情况下,就会出现问题了,为了解决这一问题,Java8提供了一套全新的API来处理日期。这些全都在java.time的包下,常用的几个如下所示:
API | 描述 |
---|---|
java.time.LocalDate、java.time.LocalTime、java.time.LocalDateTime | 日期、时间、日期时间 |
java.time.Instant | 时间戳信息 |
java.time.Duration | 计算两个时间对象之间的时间间隔,精度为纳秒 |
java.time.Period | 计算两个日期之间的时间间隔,以年、月、日为单位 |
java.time.temporal.TemporalAdjusters | 提供了一些方法用于方便的进行日期时间调整 |
java.time.format.DateTimeFormatter | 用于进行日期时间格式化和解析 |
2.2 java.time.LocalDate、java.time.LocalTime、java.time.LocalDateTime
public class DateTest02 {
public static void main(String[] args) {
//获取系统当前时间,精确到纳秒
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 2025-03-31T20:35:50.423560500
//获取指定的日期时间
LocalDateTime localDateTime = LocalDateTime.of(2024, 12, 31, 23, 50, 59, 20);
System.out.println(localDateTime); // 2024-12-31T23:50:59.000000020
//加日期和加时间
LocalDateTime localDateTime1 = localDateTime.plusDays(1);
System.out.println(localDateTime1); // 2025-01-01T23:50:59.000000020
//在这里可以接着往后进行plus操作
LocalDateTime localDateTime3 = localDateTime.plusDays(1).plusHours(1).plusMinutes(1);
System.out.println(localDateTime3); // 2025-01-02T00:51:59.000000020
//减日期和加时间
LocalDateTime localDateTime2 = localDateTime.minusDays(1);
System.out.println(localDateTime2); // 2024-12-30T23:50:59.000000020
//获取年月日等信息
int year = now.getYear();
System.out.println(year); // 2025
//这里的月份范围是1-12
int month = now.getMonthValue();
System.out.println(month); // 3
int day = now.getDayOfMonth();
System.out.println(day); // 31
int hour = now.getHour();
System.out.println(hour); // 20
int min = now.getMinute();
System.out.println(min); // 39
int sec = now.getSecond();
System.out.println(sec); // 18
}
}
2.3 Instant 时间戳
这里的时间戳基准还是1970-01-01 00:00:00
public class DateTest02 {
public static void main(String[] args) {
//获取系统当前时间
Instant instant = Instant.now();
System.out.println(instant); // 2025-03-31T12:43:36.796942600Z
//获取当前时间距离1970-01-01 00:00:00的秒数
long epochMilli = instant.toEpochMilli();
System.out.println(epochMilli); // 1743425016796
}
}
2.4 Duration 计算时间间隔
public class DateTest02 {
public static void main(String[] args) {
/**
* 计算两个时间相差的间隔
*/
LocalDateTime now1 = LocalDateTime.of(2025,3,31,20,20,8);
LocalDateTime now2 = LocalDateTime.of(2025,7,31,20,20,8);
Duration between = Duration.between(now1, now2);
// 两个时间差多少个小时
System.out.println(between.toHours()); // 2928
// 两个时间差多少天
System.out.println(between.toDays()); // 122
}
}
2.5 Period 计算日期间隔
public class DateTest02 {
public static void main(String[] args) {
/**
* 计算两个日期的间隔
*/
LocalDate now1 = LocalDate.of(2024,3,3);
LocalDate now2 = LocalDate.of(2025,7,4);
Period between = Period.between(now1, now2);
// 相差年数
System.out.println(between.getYears()); // 1
// 相差月数
System.out.println(between.getMonths()); // 4
// 相差天数
System.out.println(between.getDays()); // 1
2.6 TemporalAdjusters 时间矫正器
public class DateTest02 {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now(); // 获取系统当前时间
System.out.println(now); // 2025-03-31T20:54:16.733388800
// 当前月的第一天1
LocalDateTime localDateTime1 = now.with(TemporalAdjusters.firstDayOfMonth());
System.out.println(localDateTime1); // 2025-03-01T20:54:16.733388800
// 下一年的第一天
LocalDateTime localDateTime2 = now.with(TemporalAdjusters.firstDayOfNextYear());
System.out.println(localDateTime2); // 2026-01-01T20:54:16.733388800
// 本年最后一天
LocalDateTime localDateTime3 = now.with(TemporalAdjusters.lastDayOfYear());
System.out.println(localDateTime3); // 2025-12-31T20:54:16.733388800
// 本月最后一天
LocalDateTime localDateTime4 = now.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(localDateTime4); // 2025-03-31T20:54:16.733388800
// 下周一
LocalDateTime localDateTime5 = now.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
System.out.println(localDateTime5); // 2025-04-07T20:54:16.733388800
}
}
2.7 DateTimeFormatter 日期格式化
这里的日期格式化其实用法还是和Java8之前类似,但是有两点需要注意的地方:
- 在将日期转换为String时,Java8之后使用的是DateTimeFormatter.ofPattern(“指定的日期格式”),而Java8之前使用的是new SimpleDateFormat(“指定的日期格式”)
- 在将String转换为日期时,Java8之后使用的是LocalDateTime的parse()方法,而Java8之前是SimpleDateFormat的parse()方法
public class DateTest02 {
public static void main(String[] args) {
//将日期转换为String
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String s = dtf.format(now);
System.out.println(s); // 2025-03-31 20:58:32
//将String转换为日期
LocalDateTime localDateTime = LocalDateTime.parse(s, dtf);
System.out.println(localDateTime); // 2025-03-31T20:58:49
}
}