乐趣区

关于后端:Java-中的日期时间总结

前言

大家好,我是 god23bin,在日常开发中,咱们常常须要解决日期和工夫,日期和工夫能够说是肯定会用到的,当初总结下 Java 中日期与工夫的基本概念与一些罕用的用法。

基本概念

  1. 日期(年月日,某一天):2023-01-05
  2. 工夫(时分秒,可具体到某一天某一刻):18:00:002023-01-05 18:00:00
  3. 本地工夫:平时咱们说的,比方当初说今天早上七点钟,这里说的工夫就是本地工夫,在咱们中国,指的就是北京工夫。然而在今天早上七点钟,对于其余国家的人来说,他们的本地工夫就不一样了。
  4. 时区:因为世界各个国家与地区经度不同,本地工夫也有所不同,所以划分了不同的时区,目前划分的是 24 个时区,咱们就位于东八区。目前须要理解的时区的表达方式晓得两种就能够了。

    • GMT 或者 UTC 加时区偏移量示意,例如:GMT+08:00 或者 UTC+08:00 示意东八区
    • 洲 / 城市 示意,例如,Asia/Shanghai,示意上海所在地的时区。不过这里的城市名称不是任意的城市,而是由国际标准组织规定的城市。

Java 8 之前日期工夫相干的类

在 Java 8 之前,次要应用的日期和工夫 API 包含:

  1. java.util.Date
  2. java.util.Calendar
  3. 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 中用于 格式化日期和工夫 的类,此处所谓格式化,就是字面意思,对立格局,即它容许你将日期和工夫依照指定的格局转换成字符串,也能够将对应格局的字符串解析成日期和工夫对象。

次要用法就是:

  1. 格式化日期和工夫
  2. 解析字符串格局的日期和工夫

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 的概述:

  1. LocalDate:示意 日期,但不蕴含工夫和时区信息。它提供了各种办法来解决日期,如创立、解析、格式化、计算日期差等。
  2. LocalTime:示意 工夫,但不蕴含日期和时区信息。它用于解决工夫,包含小时、分钟、秒和毫秒。
  3. LocalDateTime:它是 LocalDateLocalTime 的组合,示意 日期和工夫,但仍不蕴含时区信息。它是解决日期和工夫的次要类之一。
  4. ZonedDateTime:示意带有 时区 信息的 日期和工夫。它是 LocalDateTime 的扩大,能够解决时区的转换和计算。
  5. Duration:示意 时间段的持续时间,以秒和纳秒为单位。它用于测量两个工夫点之间的时间差。
  6. Period:示意日期之间的时间段,以年、月和日为单位。它用于测量两个日期之间的时间差。
  7. 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;
    
}

最初的最初

心愿各位屏幕前的 靓仔靓女们 给个三连!你轻轻地点了个赞,那将在我的心里世界削减一颗亮堂而夺目的星!

咱们下期再见!

退出移动版