共计 8172 个字符,预计需要花费 21 分钟才能阅读完成。
前言
大家好,我是 god23bin,在日常开发中,咱们常常须要解决日期和工夫,日期和工夫能够说是肯定会用到的,当初总结下 Java 中日期与工夫的基本概念与一些罕用的用法。
基本概念
- 日期(年月日,某一天):
2023-01-05
- 工夫(时分秒,可具体到某一天某一刻):
18:00:00
、2023-01-05 18:00:00
- 本地工夫:平时咱们说的,比方当初说今天早上七点钟,这里说的工夫就是本地工夫,在咱们中国,指的就是北京工夫。然而在今天早上七点钟,对于其余国家的人来说,他们的本地工夫就不一样了。
-
时区:因为世界各个国家与地区经度不同,本地工夫也有所不同,所以划分了不同的时区,目前划分的是 24 个时区,咱们就位于东八区。目前须要理解的时区的表达方式晓得两种就能够了。
- 以
GMT
或者UTC
加时区偏移量示意,例如:GMT+08:00
或者UTC+08:00
示意东八区 - 以
洲 / 城市
示意,例如,Asia/Shanghai
,示意上海所在地的时区。不过这里的城市名称不是任意的城市,而是由国际标准组织规定的城市。
- 以
Java 8 之前日期工夫相干的类
在 Java 8 之前,次要应用的日期和工夫 API 包含:
java.util.Date
java.util.Calendar
java.text.SimpleDateFormat
1. Date
Date
是 Java 中示意日期和工夫的类,个别用于获取以后的日期和工夫,比方更新数据库中记录的时候,须要更新某个日期工夫,那么就间接 new Date()
,这样实例化的 Date 对象就是以后的这一时刻。
Date date = new Date();
// 能够打印以后日期工夫
System.out.println(date.toString()); // 控制台输入 Thu Jan 05 18:41:11 CST 2023
2. SimpleDateFormat
SimpleDateFormat
是 Java 中用于 格式化日期和工夫 的类,此处所谓格式化,就是字面意思,对立格局,即它容许你将日期和工夫依照指定的格局转换成字符串,也能够将对应格局的字符串解析成日期和工夫对象。
次要用法就是:
- 格式化日期和工夫
- 解析字符串格局的日期和工夫
format 办法 - 格式化日期工夫,从 Date 到 String
应用 public final String format(Date date)
办法格式化日期工夫。下面输入的格局,不是咱们想要的,所以须要进行日期工夫的格式化。
最罕用的一个格式化的模型是:yyyy-MM-dd HH:mm:ss
其中,yyyy
是年份,MM
是月份,dd
是天数,前面同理,HH:mm:ss
是时、分、秒。
// 罕用的格式化
String pattern1 = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf1 = new SimpleDateFormat(pattern1);
System.out.println(sdf1.format(date3)); // 输入 2023-01-05 18:19:50
String pattern2 = "yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒";
SimpleDateFormat sdf2 = new SimpleDateFormat(pattern2);
System.out.println(sdf2.format(date3)); // 输入 2023 年 01 月 05 日 18 时 19 分 50 秒
parse 办法 - 字符串日期工夫解析,从 String 到 Date
应用 public Date parse(String source)
办法将 String 转成 Date
String input = "2023-01-01 00:00:01";
String pattern1 = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf3 = new SimpleDateFormat(pattern1);
try {
// 将 String 类型的日期解析成 Date 类型的日期
Date parsed = sdf3.parse(input);
System.out.println(parsed);
} catch (ParseException e) {e.printStackTrace();
}
3. Calendar
Calendar
是 Java 中用于解决日期和工夫的形象基类。它提供了一个相似于日历的机制,容许咱们进行日期和工夫的计算、格式化和解析。
简而言之,这个类次要用于日期的计算,比方你想得到此刻前一天的日期。
Calendar
是一个抽象类,不能间接实例化。所以咱们须要应用 getInstance()
办法获取 Calendar
的实例:
Calendar calendar = Calendar.getInstance();
当咱们有一个 Calendar
对象后,就能够示意日期和工夫了,通过设置各个字段,如年、月、日、时、分、秒等来示意一个具体的日期和工夫。
calendar.set(Calendar.YEAR, 2023); // 设置年份为 2023
calendar.set(Calendar.MONTH, Calendar.MAY); // 设置月份为 5(从 0 开始,5 示意六月)calendar.set(Calendar.DAY_OF_MONTH, 16); // 设置日期为 16 号
日期和工夫的计算
Calendar
容许你进行日期和工夫的加减操作,例如:
calendar.add(Calendar.DAY_OF_MONTH, 7); // 减少 7 天
这将在以后日期的根底上减少 7 天。
下表列出了 Java 中 Calendar 类罕用的办法及其形容:
办法 | 形容 |
---|---|
get(int field) |
返回给定字段的值。例如,calendar.get(Calendar.MONTH) 返回月份。 |
set(int field, int value) |
设置给定字段的值。例如,calendar.set(Calendar.YEAR, 2023) 设置年份为 2023。 |
add(int field, int amount) |
减少或缩小给定字段的值。例如,calendar.add(Calendar.DAY_OF_MONTH, 1) 将日期减少一天。 |
getTime() |
返回示意此 Calendar 工夫点的 Date 对象。 |
setTime(Date date) |
应用指定的 Date 对象设置此 Calendar 的工夫点。 |
getTimeInMillis() |
返回以毫秒为单位示意此 Calendar 工夫点的工夫值。 |
setTimeInMillis(long millis) |
应用指定的工夫值设置此 Calendar 的工夫点。 |
getTimeZone() |
返回此 Calendar 应用的时区。 |
setTimeZone(TimeZone zone) |
设置此 Calendar 的时区。 |
isLenient() |
返回 Calendar 是否宽松,即是否容许非法日期。 |
setLenient(boolean lenient) |
设置 Calendar 是否宽松。 |
getActualMaximum(int field) |
返回给定字段的最大允许值。例如,calendar.getActualMaximum(Calendar.DAY_OF_MONTH) 返回以后月份的最大天数。 |
Java 8 引入的新的日期工夫相干的类
当 Java 8 引入 java.time
包时,它引入了一些新的日期和工夫 API,这些 API 旨在提供更弱小、更易于应用、线程平安且具备本地化反对的日期和工夫解决形式。
以下是这些 API 的概述:
LocalDate
:示意 日期,但不蕴含工夫和时区信息。它提供了各种办法来解决日期,如创立、解析、格式化、计算日期差等。LocalTime
:示意 工夫,但不蕴含日期和时区信息。它用于解决工夫,包含小时、分钟、秒和毫秒。LocalDateTime
:它是LocalDate
和LocalTime
的组合,示意 日期和工夫,但仍不蕴含时区信息。它是解决日期和工夫的次要类之一。ZonedDateTime
:示意带有 时区 信息的 日期和工夫。它是LocalDateTime
的扩大,能够解决时区的转换和计算。Duration
:示意 时间段的持续时间,以秒和纳秒为单位。它用于测量两个工夫点之间的时间差。Period
:示意日期之间的时间段,以年、月和日为单位。它用于测量两个日期之间的时间差。DateTimeFormatter
:次要用于将日期和工夫 格式化为字符串 ,或将字符串 解析为日期和工夫。它提供了各种预约义的格式化形式,并反对自定义格局。
1. LocalDate
间接通过调用其相干静态方法就能够进行相干的日期解决:
LocalDate now = LocalDate.now(); // 获取以后日期
LocalDate date = LocalDate.of(2023, 5, 15); // 创立指定日期
LocalDate parsedDate = LocalDate.parse("2023-05-15"); // 解析日期
int year = date.getYear(); // 获取年份
int month = date.getMonthValue(); // 获取月份
int day = date.getDayOfMonth(); // 获取日期
2. LocalTime
同理,也是相似的,对工夫进行解决:
LocalTime time = LocalTime.now(); // 获取以后工夫
LocalTime specificTime = LocalTime.of(14, 30, 0); // 创立指定工夫
LocalTime parsedTime = LocalTime.parse("14:30:00"); // 解析工夫
int hour = time.getHour(); // 获取小时
int minute = time.getMinute(); // 获取分钟
int second = time.getSecond(); // 获取秒
3. LocalDateTime
解决日期和工夫:
LocalDateTime dateTime = LocalDateTime.now(); // 获取以后日期和工夫
LocalDateTime specificDateTime = LocalDateTime.of(2023, 5, 15, 14, 30); // 创立指定日期和工夫
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-05-15T14:30:00"); // 解析日期和工夫,字母 'T' 用于分隔日期局部和工夫局部。它的作用是明确示意日期和工夫的分界线。
4. ZonedDateTime
解决带有时区的日期和工夫,咱们能够应用 ZoneId.of("时区标识")
来获取相应的时区对象:
ZoneId zone = ZoneId.of("America/New_York"); // 创立时区
ZonedDateTime zonedDateTime = ZonedDateTime.now(zone); // 获取带有时区的以后日期和工夫
带有时区信息的日期工夫通常采纳以下的格局:
2023-09-08T11:30:00+08:00[Asia/Shanghai]
这个例子示意的是 2023 年 9 月 8 日 11 点 30 分
,位于 亚洲 / 上海
时区,时区偏移量为+08:00
,也就是东八区。在这种示意中,日期工夫前面跟着时区信息,方括号内的局部为时区标识。
上面是一些常见的时区标识及其对应的时区:
时区标识 | 时区 |
---|---|
Asia/Shanghai |
中国上海时区 |
America/New_York |
美国纽约时区 |
Europe/London |
英国伦敦时区 |
America/Los_Angeles |
美国洛杉矶时区 |
Asia/Tokyo |
日本东京时区 |
Europe/Paris |
法国巴黎时区 |
Australia/Sydney |
澳大利亚悉尼时区 |
Africa/Cairo |
埃及开罗时区 |
Pacific/Honolulu |
美国檀香山时区 |
Asia/Dubai |
阿拉伯迪拜时区 |
5. Duration
测量时间段的持续时间:
LocalDateTime start = LocalDateTime.of(2023, 9, 8, 11, 0);
LocalDateTime end = LocalDateTime.of(2023, 9, 8, 11, 30);
Duration duration = Duration.between(start, end); // 计算两个工夫点之间的时间差
long minutes = duration.toMinutes(); // 获取分钟数
6. Period
测量日期之间的时间段:
LocalDate startDate = LocalDate.of(2023, 9, 1);
LocalDate endDate = LocalDate.of(2023, 9, 8);
Period period = Period.between(startDate, endDate); // 计算两个日期之间的时间差
int days = period.getDays(); // 获取天数
7. DateTimeFormatter
格式化日期和工夫:
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = dateTime.format(formatter); // 格式化为字符串
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-05-15 14:30:00", formatter); // 解析字符串为日期和工夫
新日期工夫 API 中罕用的办法
以下是 Java 8 中新日期工夫 API 中罕用的办法,用于解决日期和工夫的创立、获取字段值、计算差别、格式化和解析等:
办法 | 形容 |
---|---|
LocalDate.now() |
获取以后日期。 |
LocalTime.now() |
获取以后工夫。 |
LocalDateTime.now() |
获取以后日期和工夫。 |
LocalDate.of(int year, int month, int day) |
创立指定日期。 |
LocalTime.of(int hour, int minute) |
创立指定工夫。 |
LocalDateTime.of(int year, int month, int day, int hour, int minute) |
创立指定日期和工夫。 |
LocalDate.parse(CharSequence text) |
解析日期字符串。 |
LocalTime.parse(CharSequence text) |
解析工夫字符串。 |
LocalDateTime.parse(CharSequence text) |
解析日期工夫字符串。 |
LocalDate.getYear() |
获取年份。 |
LocalDate.getMonthValue() |
获取月份。 |
LocalDate.getDayOfMonth() |
获取日期。 |
LocalTime.getHour() |
获取小时。 |
LocalTime.getMinute() |
获取分钟。 |
LocalTime.getSecond() |
获取秒。 |
LocalDateTime.plus(Duration amount) |
减少持续时间。 |
LocalDateTime.minus(Duration amount) |
缩小持续时间。 |
Duration.between(Temporal startInclusive, Temporal endExclusive) |
计算两个工夫点之间的时间差。 |
Period.between(LocalDate startDateInclusive, LocalDate endDateExclusive) |
计算两个日期之间的时间差。 |
DateTimeFormatter.ofPattern(String pattern) |
创立日期工夫格式化器。 |
Temporal.format(DateTimeFormatter formatter) |
格式化为字符串。 |
TemporalAccessor.parse(CharSequence text, DateTimeFormatter formatter) |
解析字符串为日期或工夫。 |
ZoneId.of(String zoneId) |
创立时区。 |
ZonedDateTime.now(ZoneId zone) |
获取带有时区的以后日期和工夫。 |
开发中的用到的两个注解
个别前端传递 日期工夫字符串,咱们后端进行接管,就须要将日期工夫字符串转成咱们须要的 Date 类型的日期工夫,即 String 到 Date 的转化
当咱们从数据库中查出日期工夫,是 Date 类型的日期工夫 ,返回给前端就提供 JSON 数据,就须要讲 Date 类型的日期工夫转成 字符串类型的日期工夫,即 Date 到 String 的转化
有两个注解能够解决这两件事:Spring 提供的 @DateTimeFormat
和 Jackson 提供的 @JsonFormat
Jackson 相干依赖:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4.2</version>
</dependency>
阐明:
@DateTimeFormat
:将 String 转成 Date,次要用于解决前端传递的 String 类型的日期工夫转成 Java 中的 Date 类型的日期工夫对象@JsonFormat
:将 Date 转成 String,次要用于解决后端从数据库中查出的 Date 类型的日期工夫,它能够用于标记 Java 类的属性,以指定日期在 JSON 中的格局。
日常用在各种域对象的日期属性上,比方 DTO、VO、PO。
public class A {@JsonFormat(pattern = "yyyy 年 MM 月", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy 年 MM 月")
private Date startTime;
@JsonFormat(pattern = "yyyy 年 MM 月", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy 年 MM 月")
private Date endTime;
}
public class B {@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startTime;
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endTime;
}
最初的最初
心愿各位屏幕前的 靓仔靓女们
给个三连!你轻轻地点了个赞,那将在我的心里世界削减一颗亮堂而夺目的星!
咱们下期再见!