16_常用时间API:时间类,日期类

Java 常用时间API:时间类,日期类

JDK8 之前

Date类 : 表示日期时间的类

  1. 构造方法 :

    构造器 说明
    public Date() 创建一个Date对象,代表的是系统当前此刻日期时间。
    public Date(long time) 把时间毫秒值转换成Date日期对象。
    1
    2
    3
    4
    Date d1 = new Date(0L);
    System.out.println(d1); //Thu Jan 01 00:00:01 GMT+08:00 1970
    Date d2 = new Date(1000L);
    System.out.println(d2); //Thu Jan 01 08:00:01 GMT+08:00 1970
  2. 常见方法 :

    常见方法 说明
    public long getTime() 返回从1970年1月1日 00:00:00走到此刻的总的毫秒数
    public void setTime(long time) 设置日期对象的时间为当前时间毫秒值对应的时间

SimpleDateFormat 类:日期格式化

1.构造方法 :

构造器 说明
public SimpleDateFormat() 构造一个SimpleDateFormat日期格式化对象,使用默认格式
public SimpleDateFormat(String pattern) 构造一个SimpleDateFormat日期格式化对象,使用指定的格式

2.常见方法 :

格式化方法 说明
public final String format(Date date) 将日期对象格式化成日期时间字符串
public final Date parse(String source) 将日期字符串解析为日期类型
API中SimpleDateFormat类的指定模式规范:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static void main(String[] args) throws ParseException {       //parse 异常
//将日期对象格式化成日期时间字符串
// 创建一个使用默认模式的日期格式化对象
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat();
// 创建一个指定模式的日期格式化对象
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy年MM月dd日"); //如果只有yy,定义为年份后两位
// 创建Date对象封装此刻的时间
Date date = new Date();
// 将日期对象转换为字符串
String time = simpleDateFormat1.format(date); //2023/2/15 下午6:46
String time = simpleDateFormat2.format(date); //2023年02月15日

//将日期字符串解析为日期类型
String today = "2023年1月1日";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
Date date = simpleDateFormat.parse(today); //today必须和simpleDateFormat指定的格式相同才能解析,否则报错
System.out.println(date);
}

private static void method() {
// 创建一个日期格式化对象, 使用 [默认模式]
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat();

// 创建一个日期格式化对象, [手动指定模式]
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");

// 创建Date对象, 封装此刻的时间
Date date = new Date();

// 将日期对象, 转换为字符串
String result = simpleDateFormat.format(date);

System.out.println(result);
}

Calendar 类:系统此刻时间对应的日历,用于单独获取、修改时间中的年、月、日、时、分、秒

创建对象

注: Calendar是一个抽象类,不能直接创建对象,使用静态方法创建

方法名 说明
public static Calendar getInstance() 获取当前时间的日历对象

常用方法

方法名 说明
public int get(int field) 获取日历中的某个字段信息
public void set(int field,int value) 修改日历的某个字段信息
public void add(int field,int amount) 为某个字段增加/减少指定的值
public final Date getTime() 获取日期对象
public final setTime(Date date) 给日历设置日期对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 private static void getMethod() {
// Calendar c : 抽象类
// Calendar.getInstance() : 获取的是子类对象
// 1. 获取当前时间的日历对象
Calendar c = Calendar.getInstance();

// 2. 调用get方法, 获取指定字段的信息
int year = c.get(Calendar.YEAR);
System.out.println(year); //年

// 注意Calendar类的月份是 0~11, 常规的月份要 + 1
int month = c.get(Calendar.MONTH);
System.out.println(month + 1); //月

int day = c.get(Calendar.DAY_OF_MONTH);
System.out.println(day); //星期

//这里的星期:星期日为每周第一天,定义一个数组存放,用索引值调用
char[] weeks = {' ', '日', '一', '二', '三', '四', '五', '六'};
// 0 1 2 3 4 5 6 7

int weekIndex = c.get(Calendar.DAY_OF_WEEK);
System.out.println(weeks[weekIndex]); //日

int dayOfYear = c.get(Calendar.DAY_OF_YEAR);
System.out.println(dayOfYear); //是一年的第一天
}

private static void setMethod() {
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 2022); //设置年为2022
c.set(2000,1,1); //设置日期为:2000年1月1日,输出月份值为2
}

private static void addMethod() {
Calendar c = Calendar.getInstance();
c.add(Calendar.YEAR, -1); //年份-1
}

注:get方法的参数为Calendar类中的静态常量

​ Calendar.YEAR : 获取年
​ Calendar.MONTH : 月份是0~11, 常规日期要+1
​ Calendar.DAY_OF_MONTH : 获取日
​ Calendar.DAY_OF_WEEK : 获取星期, 但是1代表周日,7代表周六
​ Calendar.DAY_OF_YEAR : 获取一年中的第几天

实例

1.判断 2030年3月3日 周几

1
2
3
4
Calendar c = Calendar.getInstance();					// 1. 获取日期对象 (此刻的时间)
c.set(2030, 2, 3); // 2. 调用set方法, 将时间设置为 2030年3月3日; 月份设置2
char[] weeks = {' ', '日', '一', '二', '三', '四', '五', '六'};
int weekIndex = c.get(Calendar.DAY_OF_WEEK); // 3. 获取星期

2.键盘录入一个日期字符串, 判断是一年的第几天

分析:

  1. 使用SimpleDateFormat, 将日期字符串转换为日期对象
  2. 将日期对象, 转换为Calendar对象
  3. 调用get方法, 获取是一年中的第几天
1
2
3
4
5
6
7
8
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String dateContent = sc.nextLine();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日"); // 1. 使用SimpleDateFormat将日期字符串转换为日期对象
Date date = dateFormat.parse(dateContent);
Calendar c = Calendar.getInstance();
c.setTime(date); // 2. 将日期对象, 转换为Calendar对象
int dayOfYear = c.get(Calendar.DAY_OF_YEAR); // 3. 调用get方法, 获取一年中的第几天

前后对比

JDK8之前的传统的时间API

  1. 设计欠妥,使用不方便,部分已经淘汰
  2. 都是可变对象,修改后会丢失最开始的时间信息 覆盖之前的时间信息
  3. 线程不安全
  4. 只能精确到毫秒

JDK8开始之后新增的时间API

  1. 设计更合理,功能丰富,使用更方便
  2. 都是不可变对象,修改后会返回新的时间对象,不会丢失最开始的时间 每一次修改都返回一个新的对象
  3. 线程安全
  4. 能精确到毫秒、纳秒

JDK8 之后

日历类

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);
获取对象中的年月日时分秒
方法名 功能
int getYear() 获取年 字段
Month getMonth() 使用 Month 枚举获取年份字段
int getMonthValue() 获取1到12之间的月份字段
int getDayOfMonth() 获取日
DayOfWeek getDayOfWeek() 获取星期 字段,即枚举 DayOfWeek
int getHour() 获取时
int getMinute() 获取分
int getSecond() 获取秒
1
2
3
4
5
6
7
8
9
10
11
LocalDateTime now = LocalDateTime.now();				// 获取此刻的时间对象
System.out.println(now);
LocalDateTime time = LocalDateTime.of(2000, 1, 1, 1, 1); // 指定2000年1月1日1时1分
System.out.println(now.getYear() + "年");
System.out.println(now.getMonth() + "月"); // 英文字符串月份
System.out.println(now.getMonthValue() + "月"); // int型月份
System.out.println(nowDateTime.getMonth().getValue()); // 输出同上,不一样的写法
System.out.println(now.getDayOfMonth() + "日");
System.out.println("dayOfYear:" + nowDateTime.getDayOfYear());// 年的第几天
System.out.println(nowDateTime.getDayOfWeek()); // 星期
System.out.println(nowDateTime.getDayOfWeek().getValue());
修改年月日时分秒相关

LocalDateTime 、LocalDate 、LocalTime 都是不可变的, 方法返回的是一个新对象

方法名 说明
withHour、withMinute、withSecond、withNano 修改时间,返回新时间对象
plusHours、plusMinutes、plusSeconds、plusNanos 把某个信息加多少,返回新时间对象
minusHours、minusMinutes、minusSeconds、minusNanos 把某个信息减多少,返回新时间对象
equals / isBefore / isAfter 判断2个时间对象,是否相等,在前还是在后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
LocalDateTime nowTime = LocalDateTime.now();
// with : 设置
//withYear(年), withMonth(月), withDayOfMonth(日), withHour(时), withMinute(分), withSecond(秒), withNano(纳秒)
System.out.println(nowTime.withYear(2000)); //设置年2000
System.out.println(nowTime.withMonth(1)); //设置月1
System.out.println(nowTime.withDayOfMonth(1)); //设置日1
System.out.println(nowTime.withHour(1)); //设置小时1
System.out.println(nowTime.withNano(1)); //设置纳秒1
//修改原日历
nowTime = LocalDate.of(2008, 8, 8); //上面的设置不改变原先数据,要修改的话用of
// minus : 减去
System.out.println(nowTime.minusHours(1)); //减一小时
System.out.println(nowTime.minusSeconds(1)); //减一秒钟,nowTime对象不变,输出的是新对象
// plus : 加
System.out.println(nowTime.plusMinutes(1)); //加一分钟

//判断两个日期在前/在后/相等 返回true/false
System.out.println(date1.isBefore(date2));
System.out.println(date1.isAfter(date2));
System.out.println(date1.equals(date2));
LocalDateTime 转 LocalDate 和 Local Time
方法名 说明
public LocalDate toLocalDate() 转换成一个LocalDate对象
public LocalTime toLocalTime() 转换成一个LocalTime对象

——-> LocalDateTime拆分两块功能给LocalDate, LocalTime

日期格式化类

格式化时间

方法名 说明
static DateTimeFormatter ofPattern(格式) 获取格式对象
String format(时间对象) 按照指定方式格式化
解析时间 :

​ LocalDateTime.parse(“解析字符串”, 格式化对象);
​ LocalDate.parse(“解析字符串”, 格式化对象);
​ LocalTime.parse(“解析字符串”, 格式化对象);

1
2
3
4
5
6
LocalDateTime nowTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d日"); // 获取格式化对象
String gsltime = formatter.format(nowTime); // 格式化

String time = "2000年01月01日";
LocalDate parse = LocalDate.parse(time, formatter); // 解析字符串

DateTimeFormatter.ofPattern("yyyy年MM月dd日"); :不能解析2000-1-1

DateTimeFormatter.ofPattern("yyyy年M月d日"); :可以解析2000-1-1,也可以解析2000-01-01

时间类

Instant 时间戳:表示时间的类,类似Date类
方法名 说明
static Instant now() 获取当前时间的Instant对象(标准时间)
static Instant ofXxxx(long epochMilli) 根据(秒/毫秒/纳秒)获取Instant对象
ZonedDateTime atZone(ZoneId zone) 指定时区
boolean isXxx(Instant otherInstant) 判断系列的方法
Instant minusXxx(long millisToSubtract) 减少时间系列的方法
Instant plusXxx(long millisToSubtract) 增加时间系列的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 获取当前时间的Instant对象(标准时间)
Instant now = Instant.now();
System.out.println("当前时间为(世界标准时间):" + now);
System.out.println("------------------");

// 根据(秒/毫秒/纳秒)获取Instant对象
Instant instant1 = Instant.ofEpochMilli(1000);
Instant instant2 = Instant.ofEpochSecond(5);

System.out.println(instant1);
System.out.println(instant2);
System.out.println("------------------");

// 指定时区
ZonedDateTime zonedDateTime = Instant.now().atZone(ZoneId.systemDefault());
System.out.println("带时区的时间:" + zonedDateTime);
System.out.println("------------------");

// 判断系列的方法
System.out.println(now.isBefore(instant1));
System.out.println(now.isAfter(instant1));
System.out.println("------------------");

// 减少时间系列的方法
System.out.println("减1000毫秒:" + now.minusMillis(1000));
System.out.println("减5秒钟:" + now.minusSeconds(5));
System.out.println("------------------");

// 增加时间系列的方法
System.out.println("加1000毫秒:" + now.plusMillis(1000));
System.out.println("加5秒钟:" + now.plusSeconds(5));
System.out.println("------------------");
ZonedDateTime:带时区的时间类
1
2
3
4
5
Instant now = Instant.now();
System.out.println(now); //2023-02-15T13:52:18.642164400Z 世界标准时间,有8小时的时区差

ZonedDateTime zonedDateTime = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime); //2023-02-15T21:53:34.572435300+08:00[Asia/Shanghai]
方法名 说明
static ZonedDateTime now() 获取当前时间的ZonedDateTime对象
static ZonedDateTime ofXxxx(…) 获取指定时间的ZonedDateTime对象
ZonedDateTime withXxx(时间) 修改时间系列的方法
ZonedDateTime minusXxx(时间) 减少时间系列的方法
ZonedDateTime plusXxx(时间) 增加时间系列的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 获取当前时间的ZonedDateTime对象
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);
System.out.println("--------------------------");

// 获取指定时间的ZonedDateTime对象
ZonedDateTime of = ZonedDateTime.of
(2008, 8, 8, 8, 8, 8, 8,
ZoneId.systemDefault());
System.out.println(of);
System.out.println("--------------------------");

// 修改时间系列的方法
System.out.println(now.withYear(2008));
System.out.println(now.withMonth(8));
System.out.println(now.withDayOfMonth(8));
System.out.println("--------------------------");

// 减少时间系列的方法
System.out.println(now.minusYears(1));
System.out.println(now.minusMonths(1));
System.out.println(now.minusDays(1));
System.out.println("--------------------------");

// 增加时间系列的方法
System.out.println(now.plusYears(1));
System.out.println(now.plusMonths(1));
System.out.println(now.plusDays(1));
ZoneId 类:有关时区设置的类
方法名 说明
static Set getAvailableZoneIds() 获取Java中支持的所有时区
static ZoneId systemDefault() 获取系统默认时区
static ZoneId of(String zoneId) 获取一个指定时区
1
2
3
4
5
6
7
8
9
10
11
12
// 获取Java中支持的所有时区
Set<String> set = ZoneId.getAvailableZoneIds();
System.out.println(set); //输出所有时区字符串
System.out.println(set.size()); //输出支持的时区数:601

// 获取系统默认时区
ZoneId zoneId = ZoneId.systemDefault();

// 获取一个指定时区并使用
ZoneId of = ZoneId.of("Africa/Nairobi");
ZonedDateTime zonedDateTime = Instant.now().atZone(of);
System.out.println(zonedDateTime);

工具类

Duration类:计算两个“时间”间隔
1
2
3
4
5
6
7
LocalDateTime对象:data1,data2
Duration duration = Duration.between(data1, data2); // 第二个参数减第一个参数
System.out.println(duration.toDays()); // 两个时间差的天数
System.out.println(duration.toHours()); // 两个时间差的小时数
System.out.println(duration.toMinutes()); // 两个时间差的分钟数
System.out.println(duration.toMillis()); // 两个时间差的毫秒数
System.out.println(duration.toNanos()); // 两个时间差的纳秒数
Period类:计算两个“日期”间隔
1
2
3
4
5
6
LocalDate对象:day1, day2
Period period = Period.between(day1, day2); // 第二个参数减第一个参数
System.out.println(period.getYears()); // 间隔多少年
System.out.println(period.getMonths()); // 间隔的月份
System.out.println(period.getDays()); // 间隔的天数
System.out.println(period.toTotalMonths()); // 间隔总月份
ChronoUnit类:计算两个“日期”间隔
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
LocalDateTime对象:data1,data2
System.out.println("相差的年数:" + ChronoUnit.YEARS.between(data1, data2)); // 第二个参数减第一个参数
System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(data1,data2));
System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(data1,data2));
System.out.println("相差的天数:" + ChronoUnit.DAYS.between(data1,data2));
System.out.println("相差的时数:" + ChronoUnit.HOURS.between(data1,data2));
System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(data1,data2));
System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(data1,data2));
System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(data1,data2));
System.out.println("相差的微秒数:" + ChronoUnit.MICROS.between(data1,data2));
System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(data1,data2));
System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(data1,data2));
System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(data1,data2));
System.out.println("相差的世纪(百年)数:" + ChronoUnit.CENTURIES.between(data1,data2));
System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(data1,data2));
System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(data1,data2));
实例: 生日→计算年龄
1
2
3
4
5
6
7
8
9
10
11
12
Scanner sc = new Scanner(System.in);
System.out.println("输入生日: ");
String birthday = sc.nextLine();

// 1. 日期字符串转换为日期对象
LocalDate birthdayDate = LocalDate.parse(birthday, DateTimeFormatter.ofPattern("yyyy年M月d日"));

// 2. 获取今天的日期对象
LocalDate now = LocalDate.now();

// 3. 计算时间间隔
long age = ChronoUnit.YEARS.between(birthdayDate, now);

16_常用时间API:时间类,日期类
http://example.com/2023/02/15/16-Java常用时间API:时间类,日期类/
作者
zhanghao
发布于
2023年2月15日
许可协议