SimpleDateFormat类
SimpleDateFormat类就可以转换Date对象表示日期时间的显示格式。
-
我们把Date对象转换为指定格式的日期字符串这个操作,叫做日期格式化,
-
反过来把指定格式的日期符串转换为Date对象的操作,叫做日期解析。
接下来,我们先演示一下日期格式化,需要用到如下的几个方法

注意:创建SimpleDateFormat对象时,在构造方法的参数位置传递日期格式,而日期格式是由一些特定的字母拼接而来的。我们需要记住常用的几种日期/时间格式
字母 表示含义
yyyy 年
MM 月
dd 日
HH 时
mm 分
ss 秒
SSS 毫秒
EEE 星期几
a 上午/下午
"2022年12月12日" 的格式是 "yyyy年MM月dd日"
"2022-12-12 12:12:12" 的格式是 "yyyy-MM-dd HH:mm:ss"
按照上面的格式可以任意拼接,但是字母不能写错
最后,上代码演示一下
public class SimpleDateFormatTest1 {
public static void main(String[] args) throws ParseException {
// 目标:掌握SimpleDateFormat的使用。
// 1、准备一些时间
Date date = new Date();
System.out.println(date);
// 获取毫秒值
long time = date.getTime();
System.out.println(time);
// 2、格式化日期对象,和时间 毫秒值。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
String rs1 = sdf.format(date);
System.out.println(rs1);
// 毫秒值进行时间格式化
String rs2 = sdf.format(time);
System.out.println(rs2);
System.out.println("----------------------------------------------");
// 目标:掌握SimpleDateFormat解析字符串时间 成为日期对象。
String dateStr = "1999-12-1 12:12:11";
// 1、创建简单日期格式化对象 , 指定的时间格式必须与被解析的时间格式一模一样,否则程序会出bug.
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d2 = sdf2.parse(dateStr);
System.out.println(d2);
}
}
public class SimpleDateFormatDemo {
public static void main(String[] args) throws ParseException {
// 目标:完成秒杀案例。
// 1、把开始时间、结束时间、小贾下单时间、小皮下单时间拿到程序中来。
String start = "2023年11月11日 0:0:0";
String end = "2023年11月11日 0:10:0";
String xj = "2023年11月11日 0:01:18";
String xp = "2023年11月11日 0:10:57";
// 2、把字符串的时间解析成日期对象。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date startDt = sdf.parse(start);
Date endDt = sdf.parse(end);
Date xjDt = sdf.parse(xj);
Date xpDt = sdf.parse(xp);
// 3、开始判断小皮和小贾是否秒杀成功了。
// 把日期对象转换成时间毫秒值来判断
long startTime = startDt.getTime();
long endTime = endDt.getTime();
long xjTime = xjDt.getTime();
long xpTime = xpDt.getTime();
if(xjTime >= startTime && xjTime <= endTime){
System.out.println("小贾您秒杀成功了~~");
}else {
System.out.println("小贾您秒杀失败了~~");
}
if(xpTime >= startTime && xpTime <= endTime){
System.out.println("小皮您秒杀成功了~~");
}else {
System.out.println("小皮您秒杀失败了~~");
}
}
}
Calendar类
需求:将2023年09月10日 增加一个月
实现步骤:
1. 定义字符串记住: 2023年09月10日
2. 把字符串时间解析成Date日期对象
3. 通过Date日期对象获取2023年9月10日的毫秒值
4. 增加一个月的毫秒值:1000 * 60 * 60 * 24 * 30
5. 再格式化时间毫秒值得到结果:2023年10月10日
用Date类就不太好做,而用Calendar就特别方便。因为Calendar类提供了方法可以直接对日历中的年、月、日、时、分、秒等进行运算。 
Calendar日历类的常见方法
| 方法名 | 说明 |
|---|---|
| public static Calendar getInstance() | 获取当前日历对象 |
| public int get(int field) | 获取日历中的某个信息。 |
| public final Date getTime() | 获取日期对象。 |
| public long getTimeInMillis() | 获取时间毫秒值 |
| public void set(int field,int value) | 修改日历的某个信息。 |
| public void add(int field,int amount) | 为某个信息增加/减少指定的值 |
注意:calendar是可变对象,一旦修改后其对象本身表示的时间将产生变化。
public class CalendarTest {
public static void main(String[] args) {
// 目标:掌握Calendar的使用和特点。
// 1、得到系统此刻时间对应的日历对象。
Calendar now = Calendar.getInstance();
// 打印系统此刻时间的全部信息
System.out.println(now);
// 2、获取日历中的某个信息
// 获取年
int year = now.get(Calendar.YEAR);
System.out.println(year);
// 获取月
int month = now.get(Calendar.MONTH) + 1;
System.out.println(month);
// 获取日
int days = now.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
// 3、拿到日历中记录的日期对象。
Date date = now.getTime();
System.out.println(date);
// 4、拿到时间毫秒值
long time = now.getTimeInMillis();
System.out.println(time);
// 5、修改日历中的某个信息
now.set(Calendar.MONTH, 11); // 修改月份成为 11 月份。
now.set(Calendar.DAY_OF_YEAR, 125); // 修改成一年中的第 125 天。
System.out.println(now);
// 6、为某个信息增加或者减少多少
now.add(Calendar.DAY_OF_YEAR, 100);
now.add(Calendar.DAY_OF_YEAR, -10);
now.add(Calendar.DAY_OF_MONTH, 6);
now.add(Calendar.HOUR, 12);
System.out.println(now);
}
}
为什么JDK8要新增日期类
/**
* 目标:搞清楚为什么要用JDK 8开始新增的时间类。
*/
public class Test {
public static void main(String[] args) {
// 传统的时间类(Date、SimpleDateFormat、Calendar)存在如下问题:
// 1、设计不合理,使用不方便,很多都被淘汰了。
Date d = new Date();
System.out.println(d.getYear()); // 获取的是125, 而不是现在的2025年
System.out.println(d.getYear() + 1900);
// Calendar也不是很合理, 因为需要去记住日历的每个字段信息
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
System.out.println(year);
/**
* 2、都是可变对象,修改后会丢失最开始的时间信息。
* 比如:
* Calendar.set()方法, 重新设置后当前的日期就获取不到了
* Date.setTime(time)方法, 重新设置后之前的信息就获取不到了
*/
/**
* 3、线程不安全。(后边知识会学习)
* 了解下: 比如有很多用户会一起用时间对象, 如果其中一个人把时间修改了,
* 另一个人也把时间进行了修改, 最终获取的时间是以哪个人为主, 就会产生冲突.
*/
/**
* 4、不能精确到纳秒,只能精确到毫秒。
* 1秒 = 1000毫秒
* 1毫秒 = 1000微妙
* 1微妙 = 1000纳秒
*/
}
}
JDK8日期、时间、日期时间**(重点)**
JDK8新增的日期类分得更细致一些,比如表示年月日用LocalDate类、表示时分秒用LocalTime类、而表示年月日时分秒用LocalDateTime类等;除了这些类还提供了对时区、时间间隔进行操作的类等。它们几乎把对日期/时间的所有操作都通过了API方法,用起来特别方便。
JDK8新增的时间

先学习表示日期、时间、日期时间的类;有LocalDate、LocalTime、以及LocalDateTime类。仔细阅读代码,你会发现这三个类的用法套路都是一样的。
LocalDate:代表本地日期(年、月、日、星期)
LocalTime:代表本地时间(时、分、秒、纳秒)
LocalDateTime:代表本地日期、时间(年、月、日、星期、时、分、秒、纳秒)
它们获取对象的方案
| 方法名 | 实例 |
|---|---|
| public static Xxxx now(): 获取系统当前时间对应的该对象 | LocaDate ld = LocalDate.now(); LocalTime lt = LocalTime.now(); LocalDateTime ldt = LocalDateTime.now(); |
| public static Xxxx of(...):获取指定时间的对象 | LocalDate localDate1 = LocalDate.of(2099 , 11,11); LocalTime localTime1 = LocalTime.of(9, 8, 59); LocalDateTime localDateTime1 = LocalDateTime.of(2025, 11, 16, 14, 30, 01); |
- LocalDate类的基本使用
LocalDate的常用API(都是处理年、月、日、星期相关的)。
| 方法名 | 说明 |
|---|---|
| public int getYear() | 获取年 |
| public int getMonthValue() | 获取月份(1-12) |
| public int getDayOfMonth() | 获取日 |
| public int getDayOfYear() | 获取当前是一年中的第几天 |
| Public DayOfWeek getDayOfWeek() | 获取星期几:ld.getDayOfWeek().getValue() |
| withYear、withMonth、withDayOfMonth、withDayOfYear | 直接修改某个信息,返回新日期对象 |
| plusYears、plusMonths、plusDays、plusWeeks | 把某个信息加多少,返回新日期对象 |
| minusYears、minusMonths、minusDays,minusWeeks | 把某个信息减多少,返回新日期对象 |
| equals isBefore isAfter | 判断两个日期对象,是否相等,在前还是在后 |
下面看代码,演示一下
public class LocalDateTest {
public static void main(String[] args) {
// 0、获取本地日期对象(不可变对象)
LocalDate ld = LocalDate.now(); // 年 月 日
System.out.println(ld);
System.out.println("----------------------");
// 1、获取日期对象中的信息
int year = ld.getYear(); // 年
int month = ld.getMonthValue(); // 月(1-12)
int day = ld.getDayOfMonth(); // 日
int dayOfYear = ld.getDayOfYear(); // 一年中的第几天
int dayOfWeek = ld.getDayOfWeek().getValue(); // 星期几
System.out.println(year);
System.out.println(month);
System.out.println(day);
System.out.println(dayOfYear);
System.out.println(dayOfWeek);
System.out.println("----------------------");
// 2、直接修改某个信息: withYear、withMonth、withDayOfMonth、withDayOfYear
LocalDate ld2 = ld.withYear(2099); // 修改年
System.out.println(ld2);
LocalDate ld3 = ld.withMonth(12); // 修改月
System.out.println(ld3);
System.out.println(ld); // 原始时间不会发生改变
System.out.println("----------------------");
// 3、把某个信息加多少: plusYears、plusMonths、plusDays、plusWeeks
LocalDate ld4 = ld.plusYears(2);
System.out.println(ld4);
LocalDate ld5 = ld.plusMonths(2);
System.out.println(ld5);
System.out.println("----------------------");
// 4、把某个信息减多少:minusYears、minusMonths、minusDays、minusWeeks
LocalDate ld6 = ld.minusYears(2);
System.out.println(ld6);
LocalDate ld7 = ld.minusMonths(2);
System.out.println(ld7);
System.out.println("----------------------");
// 5、获取指定日期的LocalDate对象: public static LocalDate of(int year, int month, int dayOfMonth)
LocalDate ld8 = LocalDate.of(2099, 12, 12);
System.out.println(ld8);
LocalDate ld9 = LocalDate.of(2099, 12, 12);
System.out.println(ld9);
// 6、判断2个日期对象,是否相等,在前还是在后: equals isBefore isAfter
System.out.println(ld8.equals(ld9)); // 日期是否相等 true
System.out.println(ld8.isAfter(ld)); // 当前时间是否在ld之后 true
System.out.println(ld8.isBefore(ld)); // 当前时间是否在ld之前 false
}
}
- LocalTime类的基本使用
LocalTime的常用API(都是处理时、分、秒、纳秒相关的)。
| 方法名 | 说明 |
|---|---|
| public int getHour() | 获取小时 |
| public int getMinute() | 获取分 |
| public int getSecond() | 获取秒 |
| public int getNano() | 获取纳秒 |
| withHour、withMinute、withSecond、withNano | 修改时间,返回新时间对象 |
| plusHours、plusMinutes、plusSeconds、plusNanos | 把某个信息加多少,返回新时间对象 |
| minusHours、minusMinutes、minusSeconds、minusNanos | 把某个信息减多少,返回新时间对象 |
| equals isBefore isAfter | 判断2个时间对象,是否相等,在前还是在后 |
下面看代码,演示一下
public class LocalTimeTest {
public static void main(String[] args) {
// 0、获取本地时间对象
LocalTime lt = LocalTime.now(); // 时 分 秒 纳秒 不可变的
System.out.println(lt);
// 1、获取时间中的信息
int hour = lt.getHour(); //时
int minute = lt.getMinute(); //分
int second = lt.getSecond(); //秒
int nano = lt.getNano(); //纳秒
// 2、修改时间:withHour、withMinute、withSecond、withNano
LocalTime lt3 = lt.withHour(10);
LocalTime lt4 = lt.withMinute(10);
LocalTime lt5 = lt.withSecond(10);
LocalTime lt6 = lt.withNano(10);
// 3、加多少:plusHours、plusMinutes、plusSeconds、plusNanos
LocalTime lt7 = lt.plusHours(10);
LocalTime lt8 = lt.plusMinutes(10);
LocalTime lt9 = lt.plusSeconds(10);
LocalTime lt10 = lt.plusNanos(10);
// 4、减多少:minusHours、minusMinutes、minusSeconds、minusNanos
LocalTime lt11 = lt.minusHours(10);
LocalTime lt12 = lt.minusMinutes(10);
LocalTime lt13 = lt.minusSeconds(10);
LocalTime lt14 = lt.minusNanos(10);
// 5、获取指定时间的LocalTime对象:
// public static LocalTime of(int hour, int minute, int second)
LocalTime lt15 = LocalTime.of(12, 12, 12);
LocalTime lt16 = LocalTime.of(12, 12, 12);
// 6、判断2个时间对象,是否相等,在前还是在后: equals isBefore isAfter
System.out.println(lt15.equals(lt16)); // true
System.out.println(lt15.isAfter(lt)); // false
System.out.println(lt15.isBefore(lt)); // true
}
}
- LocalDateTime类的基本使用
LocalDateTime的常用API(可以处理年、月、日、星期、时、分、秒、纳秒等信息)
| 方法名 | 说明 |
|---|---|
| getYear、getMonthValue、getDayOfMonth、getDayOfYear、getDayOfWeek、getHour、getMinute、getSecond、getNano | 获取年月日、时分秒、纳秒等 |
| withYear、withMonth、withDayOfMonth、withDayOfYear、withHour、withMinute、withSecond、withNano | 修改某个信息,返回新日期时间对象 |
| plusYears、plusMonths、plusDays、plusWeeks、plusHours、plusMinutes、plusSeconds、plusNanos | 把某个信息加多少,返回新日期时间对象 |
| minusYears、minusMonths、minusDays、minusWeeks、minusHours、minusMinutes、minusSeconds、minusNanos | 把某个信息减多少,返回新日期时间对象 |
| equals isBefore isAfter | 判断2个时间对象,是否相等,在前还是在后 |
下面看代码,演示一下
public class LocalDateTimeTest {
public static void main(String[] args) {
// 0、获取本地日期和时间对象。
LocalDateTime ldt = LocalDateTime.now(); // 年 月 日 时 分 秒 纳秒
System.out.println(ldt);
// 1、可以获取日期和时间的全部信息
int year = ldt.getYear(); // 年
int month = ldt.getMonthValue(); // 月
int day = ldt.getDayOfMonth(); // 日
int dayOfYear = ldt.getDayOfYear(); // 一年中的第几天
int dayOfWeek = ldt.getDayOfWeek().getValue(); // 获取是周几
int hour = ldt.getHour(); //时
int minute = ldt.getMinute(); //分
int second = ldt.getSecond(); //秒
int nano = ldt.getNano(); //纳秒
// 2、修改时间信息:
// withYear withMonth withDayOfMonth withDayOfYear withHour
// withMinute withSecond withNano
LocalDateTime ldt2 = ldt.withYear(2029);
LocalDateTime ldt3 = ldt.withMinute(59);
// 3、加多少:
// plusYears plusMonths plusDays plusWeeks plusHours plusMinutes plusSeconds plusNanos
LocalDateTime ldt4 = ldt.plusYears(2);
LocalDateTime ldt5 = ldt.plusMinutes(3);
// 4、减多少:
// minusDays minusYears minusMonths minusWeeks minusHours minusMinutes minusSeconds minusNanos
LocalDateTime ldt6 = ldt.minusYears(2);
LocalDateTime ldt7 = ldt.minusMinutes(3);
// 5、获取指定日期和时间的LocalDateTime对象:
// public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour,
// int minute, int second, int nanoOfSecond)
LocalDateTime ldt8 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);
LocalDateTime ldt9 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);
// 6、 判断2个日期、时间对象,是否相等,在前还是在后: equals、isBefore、isAfter
System.out.println(ldt9.equals(ldt8));
System.out.println(ldt9.isAfter(ldt));
System.out.println(ldt9.isBefore(ldt));
System.out.println("--------------------------");
// 7、可以把LocalDateTime转换成LocalDate和LocalTime
// public LocalDate toLocalDate()
// public LocalTime toLocalTime()
// public static LocalDateTime of(LocalDate date, LocalTime time)
LocalDate ld = ldt.toLocalDate();
System.out.println(ld);
LocalTime lt = ldt.toLocalTime();
System.out.println(lt);
// 合并LocalDateTime对象
LocalDateTime ldt10 = LocalDateTime.of(ld, lt);
System.out.println(ldt10);
}
}
JDK8日期(时区)
ZoneId 时区的常见方法
| 方法名 | 说明 |
|---|---|
| public static Set<String> getAvailableZoneIds() | 获取Java中支持的所有时区 |
| public static ZoneId systemDefault() | 获取系统默认时区 |
| public static ZoneId of(String zoneId) | 获取一个指定时区 |
ZonedDateTime 带时区时间的常见方法
| 方法名 | 说明 |
|---|---|
| public static ZonedDateTime now() | 获取当前时区的ZonedDateTime对象 |
| public static ZonedDateTime now(ZoneId zone) | 获取指定时区的ZonedDateTime对象 |
| getYear、getMonthValue、getDayOfMonth、getDayOfYeargetDayOfWeek、getHour、getMinute、getSecond、getNano | 获取年月日、时分秒、纳秒等 |
| public ZonedDateTime withXxx(时间) | 修改时间系列的方法 |
| public ZonedDateTime minusXxx(时间) | 减少时间系列的方法 |
| public ZonedDateTime plusXxx(时间) | 增加时间系列的方法 |
下面看代码,演示一下
public class ZoneId_ZonedDateTime {
public static void main(String[] args) {
// 目标:了解时区和带时区的时间。
// 1、ZoneId的常见方法:
// public static ZoneId systemDefault(): 获取系统默认的时区
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId.getId());
System.out.println(zoneId); //zoneId输出时实际调用的是toString()方法
System.out.println("-----------------------");
// public static Set<String> getAvailableZoneIds(): 获取Java支持的全部时区Id
System.out.println(ZoneId.getAvailableZoneIds());
System.out.println("-----------------------");
// public static ZoneId of(String zoneId) : 把某个时区id封装成ZoneId对象。
ZoneId zoneId1 = ZoneId.of("America/New_York");
System.out.println(zoneId1);
System.out.println("========================");
// 2、ZonedDateTime:带时区的时间。
// public static ZonedDateTime now(ZoneId zone): 获取某个时区的ZonedDateTime对象。
ZonedDateTime now = ZonedDateTime.now(zoneId1);
System.out.println(now);
// 世界标准时间了
ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());
System.out.println(now1);
// public static ZonedDateTime now():获取系统默认时区的ZonedDateTime对象
ZonedDateTime now2 = ZonedDateTime.now();
System.out.println(now2);
// 扩展知识点: Calendar也可以获取时区信息
Calendar instance = Calendar.getInstance(TimeZone.getTimeZone(zoneId1));
System.out.println(instance);
}
}