Java中日期时间在企业级后台开发中的应用
Java中的日期时间类型,请系统介绍一下,并介绍一下在企业级后台开发中的应用
Java中的日期和时间处理在过去经历了多个版本的变迁,从最初的java.util.Date、java.util.Calendar到Java 8引入的全新日期/时间API(JSR-310),使得日期和时间的处理更为方便和强大。以下是对Java中关键日期时间类型的介绍及其在企业级后台开发中的应用:
Java 8之前的日期时间类(已逐渐被弃用)
-
java.util.Date
表示特定的瞬间,精确到毫秒。尽管它包含了日期和时间信息,但由于其设计缺陷,通常不建议直接使用Date进行复杂的日期时间操作。
-
java.util.Calendar
这是一个抽象类,提供了更丰富的日期和时间字段的操作,如年、月、日、时、分、秒等。它是基于Date的,但提供了一种更面向对象的方式来设置和获取日期时间字段。然而,Calendar的API被认为较为复杂和易出错。
-
java.sql.Date, Time, Timestamp(
不推荐使用
)这三个类是 java.util.Date 的子类,最初设计用于与SQL数据库交互时对应SQL的DATE、TIME和TIMESTAMP数据类型。不推荐使用,即使在Java8之前版本,也不推荐使用。
java.sql.Date
:仅存储日期部分,无时分秒信息。java.sql.Time
:仅存储时间部分,无日期信息。java.sql.Timestamp
:存储日期和时间,并且可能提供更高的精度,包括纳秒级的时间戳。
Java 8及之后的日期时间API(推荐)
自Java 8起引入了全新的日期/时间API,位于 java.time
包下,提供了更丰富的功能和更好的设计。
-
java.time.LocalDate:只包含年、月、日信息,用于表示日期部分。
-
java.time.LocalTime:只包含时、分、秒和纳秒信息,用于表示时间部分。
-
java.time.LocalDateTime:结合了LocalDate和LocalTime,表示日期和时间的完整信息,但不含时区。
-
java.time.ZonedDateTime:增加了时区信息,用于处理具有时区含义的日期和时间。
-
java.time.OffsetDateTime:类似于ZonedDateTime,但是使用偏移量而不是具体的时区ID来表示与UTC的时间差。
-
java.time.Instant:表示的是时间线上的一个瞬时点,总是相对于1970-01-01T00:00:00Z(UTC)的持续时间,类似Unix时间戳。
-
Period 和 Duration: 分别用于表示日期间隔和时间间隔。
在企业级后台开发中的应用
-
数据持久化:在数据库交互时,这些类型可以直接映射到数据库的日期和时间类型字段上,例如MySQL的DATE、TIME、DATETIME或TIMESTAMP,Oracle的DATE或TIMESTAMP WITH TIME ZONE等。
-
业务逻辑处理:在实现诸如订单有效期计算、用户活跃统计、财务报表生成等业务场景时,新的日期时间API提供了简洁的API来进行加减日期、比较日期、格式化输出等操作。
-
国际化支持:通过时区相关的类可以轻松处理跨国业务中的日期时间问题,比如不同地区的夏令时调整。
-
定时任务调度:在Quartz Scheduler等任务调度框架中,可以利用这些类型准确地定义任务的执行时间。
-
序列化与反序列化:在JSON或其他数据格式的转换过程中,能够更好地保持日期时间的精度和时区信息。
总之,在企业级后台开发中,Java 8以后的日期时间API因其强类型、易于理解且不易出错的特点而广泛应用于各种与日期和时间相关的功能模块中,极大地提高了代码的可读性和维护性。
java.sql.Date, Time, Timestamp,不推荐使用
在Java 8及更高版本中,对于数据库相关的日期和时间处理,不推荐
直接使用 java.sql.Date
、Time
和 Timestamp
类。这些类是JDBC时代的遗留物,设计上存在一些局限性,并且由于它们基于已经被弃用的 java.util.Date
类而具有相似的问题。
自Java 8以来,引入了全新的日期/时间API(位于 java.time
包下),提供了更强大、更易于理解和使用的类来处理日期和时间:
- 对于仅日期,应使用
java.time.LocalDate
。 - 对于仅时间,应使用
java.time.LocalTime
。 - 对于日期和时间合并,应使用
java.time.LocalDateTime
。 - 如果需要时区支持,则可以使用
java.time.ZonedDateTime
。
在与数据库交互时,现代的JDBC驱动程序已经更新以支持新的 java.time
类型。例如,当你准备SQL语句时,可以直接设置或获取 LocalDate
、LocalTime
或 LocalDateTime
等对象,无需先转换为旧的 java.sql.*
类型。
因此,在现代企业级后台开发中,建议优先使用 java.time
包中的类进行日期和时间的操作,而非 java.sql.Date
、Time
和 Timestamp
。这样不仅能够提高代码质量,也便于处理更多复杂的时间相关场景。
Java同时提供无时区的时间和有时区的时间
Java同时提供无时区的时间和有时区的时间,这样做的原因是什么?
Java同时提供无时区的时间和有时区的时间,主要是为了满足不同场景下的需求,并且更好地处理全球不同时区的时间表示和计算问题。
-
无时区的时间:
java.util.Date
类(在Java 8之前广泛使用)虽然内部存储的是UTC时间戳(从1970-01-01T00:00:00Z开始的毫秒数),但它并不直接包含时区信息。在显示或格式化时,需要结合具体的TimeZone对象来调整为特定地区的日期和时间。- 在Java 8中引入的
java.time.LocalDateTime
类型也是不带时区的,它仅表示一个日期和时间点,而不涉及任何地理位置或时区概念。这对于那些不需要考虑时区差异、只关心本地日期和时间的情况非常有用。
-
有时区的时间:
java.util.TimeZone
和java.util.Calendar
在旧版Java API中用于处理时区相关的任务,但它们使用起来相对复杂。- Java 8引入的新的日期时间API提供了更直观、功能更全面的类来处理时区相关的时间,例如
java.time.ZonedDateTime
。这个类将日期、时间及时区信息整合在一起,确保能够准确地表示地球上的某一时刻对于某个特定时区的意义。
这样的设计允许开发者根据实际业务逻辑选择合适的数据类型:
- 当数据代表一个绝对的世界时间时,可以使用无时区的时间,这样在全世界所有地方都能一致地理解该时间点。
- 当需要明确记录事件发生于哪个时区或者在跨时区通信和协调时,就需要使用有时区的时间类型,以避免因时区转换导致的误解。
这种灵活性有助于简化开发过程中的时间和日期管理,并增强了代码的可读性和准确性。
Java带时区的日期类型
Java中,带时区的日期类型,是什么?在企业级开发中怎么用?
在Java 8及更高版本中,为了更好地处理日期、时间和时区相关的功能,引入了全新的日期时间API。java.time.ZonedDateTime
是这个新API中的一个核心类,用于表示带有时区信息的日期和时间。
ZonedDateTime
类不仅可以存储日期(年、月、日)和时间(时、分、秒、纳秒),还包含了具体的时区信息,因此它可以精确地表示某个特定地点的时间点。这对于需要进行跨时区操作的企业级应用开发非常有用,尤其是在处理全球性的业务逻辑、日志记录、事件调度以及用户界面展示时尤为关键。
使用 ZonedDateTime
的基本步骤和示例包括:
-
创建
ZonedDateTime
对象:// 获取当前系统默认时区的当前时间 ZonedDateTime now = ZonedDateTime.now(); // 指定时区创建特定时间 ZoneId zoneId = ZoneId.of("America/New_York"); ZonedDateTime newYorkTime = ZonedDateTime.of(2024, 3, 16, 10, 0, 0, 0, zoneId);
-
格式化和解析:
// 使用DateTimeFormatter进行格式化 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z"); String formatted = newYorkTime.format(formatter); // 解析字符串为ZonedDateTime ZonedDateTime parsedTime = ZonedDateTime.parse(formatted, formatter);
-
进行时区转换:
ZoneId londonZone = ZoneId.of("Europe/London"); ZonedDateTime londonTime = newYorkTime.withZoneSameInstant(londonZone);
-
进行日期时间运算:
// 加上一段时间 ZonedDateTime futureTime = newYorkTime.plusDays(1).plusHours(3); // 减去一段时间 ZonedDateTime pastTime = newYorkTime.minusMonths(1);
在企业级开发中,ZonedDateTime
被广泛应用于国际化场景,确保数据的一致性和准确性,避免因时区问题导致的数据误解或错误。相比旧版的 Date
和 Calendar
类,新的日期时间API更加直观、易于理解和使用,并且提供了更多的函数来处理复杂的时间计算和调整问题。
Java不带时区的日期类型
Java中,不带时区的日期类型,是什么?在企业级开发中怎么用?
在Java 8及更高版本中,不带时区的日期类型主要有以下几种:
-
LocalDate:
java.time.LocalDate
类表示的是一个纯粹的日期,它只包含年、月、日信息,没有时间部分和时区概念。在企业级开发中,当你只需要处理生日、纪念日、合同生效日期等仅与日期相关的业务场景时,可以使用此类型。
示例用法:
LocalDate dateOfBirth = LocalDate.of(1990, Month.JANUARY, 1);
-
LocalTime:
java.time.LocalTime
类表示一天中的时间,包括小时、分钟、秒和纳秒,但不包含日期或时区信息。在需要处理航班时刻、商店营业时间等独立于日期的时间段时会用到这个类型。
示例用法:
LocalTime openingTime = LocalTime.of(9, 0); // 9:00 AM
-
LocalDateTime:
-
java.time.LocalDateTime
类结合了LocalDate
和LocalTime
,代表了一个完整的日期和时间,但仍然没有时区信息。在应用程序中存储或处理具体事件发生的确切日期和时间(但不需要考虑时区差异)时,会使用此类型。 -
Spring Boot应用程序中,对于那些需要完整日期和时间信息的业务逻辑处理,以及RESTful API返回详细的日期时间信息给前端时,都会用到LocalDateTime。
-
示例用法:
// 2024年3月16日 14:30 LocalDateTime eventStart = LocalDateTime.of(2024, Month.MARCH, 16, 14, 30);
-
在企业级开发中,使用这些类型的优点在于:
- 提供了清晰的语义,有助于代码的可读性和维护性。
- 提供了大量的便捷方法用于日期和时间的计算、格式化和解析。
- 避免了旧版
java.util.Date
和Calendar
类型的非直观性和易出错性。
例如,在数据库交互时,如果PostgreSQL表中的字段是无时区的时间戳类型(timestamp without time zone),那么从数据库读取或写入数据时,可以将该字段映射为Java中的 LocalDateTime
类型。
// 使用JDBC与数据库交互时
String sql = "SELECT start_date FROM my_table WHERE ...";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
LocalDateTime startDate = rs.getObject("start_date", LocalDateTime.class);
// 处理startDate...
}
}
另外,如果需要进行时区相关的转换或者操作跨越多个时区的数据,可以配合 ZonedDateTime
或 OffsetDateTime
类来完成。
在Spring Boot中,推荐使用Java 8引入的java.time包下的时间日期API,因为它们是不可变的、线程安全的,并提供了丰富的API进行各种日期和时间的操作,同时也更好地遵循ISO-8601标准,使得日期和时间的处理更加直观和便捷。同时,Spring Boot内部也已经很好地支持了这些新API,比如在转换器(Converter)、格式化(Formatter)等方面都进行了适配。
SpringBoot与Java日期时间
Java中的日期时间类型,请系统介绍一下,在SpringBoot项目中的应用
在Spring Boot项目中,处理日期和时间类型时通常会使用Java 8引入的java.time
包中的类,如LocalDate
、LocalTime
和LocalDateTime
,以及可能仍然存在的旧版java.util.Date
和java.util.Calendar
。Spring Boot通过与Jackson JSON库集成来支持这些类型的序列化和反序列化。
java.time
包下的类:
-
LocalDate
:表示没有时区信息的日期(年-月-日)。- 在Spring Boot应用中,如果你希望API接收和返回不含时间部分的日期字符串,可以通过在Controller方法参数或实体类字段上使用
@DateTimeFormat
注解指定日期格式,并配置全局日期格式化规则以统一处理。
- 在Spring Boot应用中,如果你希望API接收和返回不含时间部分的日期字符串,可以通过在Controller方法参数或实体类字段上使用
-
LocalDateTime
:表示没有时区信息的日期和时间(年-月-日 时:分:秒)。- 若要从请求参数中接收一个字符型日期时间并转换为
LocalDateTime
,同样可以使用@DateTimeFormat
注解。 - 配置全局日期格式可以在
application.properties
或application.yml
文件中进行,例如:spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss
- 若要从请求参数中接收一个字符型日期时间并转换为
-
ZonedDateTime
:包含时区信息的日期和时间。
旧版类:
java.util.Date
和java.sql.Date
:虽然不是推荐使用的日期时间类,但在遗留系统或者与JDBC交互时可能会遇到。为了兼容性,Spring Boot也提供了处理机制。如果需要将JSON中的字符串转换为Date
对象,可以通过配置Jackson的ObjectMapper
实现。
Spring Boot中的处理方式:
-
全局配置:
- 通过Spring Boot的配置属性来自定义全局日期时间格式。
-
注解驱动:
- 使用
@DateTimeFormat
注解在控制器的方法参数或实体类字段上,指定日期时间的格式。
- 使用
-
Jackson序列化/反序列化配置:
- 自动配置下,Spring Boot会自动注册
JavaTimeModule
到Jackson的ObjectMapper
中,以支持java.time
包下的类的JSON序列化和反序列化。 - 如果需要自定义时区或格式,可以通过创建自定义的
ObjectMapper
bean来进行更细粒度的控制。
- 自动配置下,Spring Boot会自动注册
-
REST API输入和输出:
- 对于RESTful接口,前端传递的日期时间字符串会在进入Controller时根据注解或全局配置自动转换为对应的日期时间对象。而返回给前端的对象则会被自动转换为符合配置格式的字符串。
-
数据库交互:
- 在与数据库交互时,Spring Data JPA等框架通常能很好地处理
java.time
类,但可能需要额外配置Hibernate等持久层框架以正确映射数据库字段。
- 在与数据库交互时,Spring Data JPA等框架通常能很好地处理
综上所述,在Spring Boot项目中,Java日期时间类型的使用涉及到从请求参数解析、数据模型绑定、JSON序列化与反序列化、数据库存取等多个环节,Spring Boot提供了一系列便捷的方式帮助开发者高效地管理这些过程。
MyBatis与Java8日期时间
如果ORM框架使用的是最新版的Mybatis,Java中的日期时间类型,会有哪些影响?
在使用最新版的MyBatis作为ORM框架时,Java中的日期时间类型(如java.time.LocalDate
、java.time.LocalTime
和java.time.LocalDateTime
等)处理的影响包括:
-
内置支持:
最新版的MyBatis已经考虑到了Java 8及更高版本中日期时间类型的广泛使用,并且通常会内置对这些类型的支持。这意味着开发者无需手动配置TypeHandler来处理与数据库字段之间的转换。 -
映射配置简化:
在Mapper XML文件或注解式映射中,可以直接声明这些日期时间类型作为参数或结果类型,MyBatis会自动进行正确的数据类型转换。 -
Spring Boot集成:
如果项目是基于Spring Boot构建的,那么通过集成MyBatis starter,可以享受到更便捷的自动配置服务,包括日期时间类型的处理,只需遵循标准的Java类型即可。 -
性能优化:
新版本可能会针对日期时间类型的处理进行性能优化,比如减少不必要的对象创建和转换操作,提高数据库交互效率。 -
兼容性增强:
MyBatis新版本会保持与当前主流数据库驱动程序的良好兼容性,确保日期时间类型的转换在不同数据库系统上都能正常工作。 -
最佳实践更新:
随着时间推移,官方文档和社区的最佳实践也会不断更新,关于如何在MyBatis中有效管理和操作日期时间类型的指导将更加成熟和完善。
因此,在实际开发中,使用最新版Mybatis时可以更为便捷地处理Java 8及其以上版本的日期时间类型,从而提升开发效率和代码质量。
注:本节说的MyBatis版本,是指自Mybatis 3.4.5之后的版本。
MyBatis默认的日期时间类型的对应关系
MySQL与Java
如果使用的是最新版的Mybatis,MySQL和Java日期时间类型是如何对应的?
MySQL和Java中的日期时间类型对应关系如下:
MySQL 数据库中的日期时间类型:
DATE
:只包含年月日,没有时分秒部分。TIME
:仅表示时间,不包含日期。DATETIME
:包含年、月、日、时、分、秒,精度到秒。TIMESTAMP
:也包含年月日时分秒,但根据MySQL版本不同,精度可以达到微秒级别,并且该类型字段在插入新记录或更新时会自动获取当前时间(可配置是否自动更新)。YEAR
:表示年份。
Java 8及更高版本中对应的日期时间类型:
- Java 8 新增的时间日期API:
java.time.LocalDate
对应 MySQL 中的DATE
类型。java.time.LocalTime
对应 MySQL 中的TIME
类型。java.time.LocalDateTime
对应 MySQL 中的DATETIME
类型。java.time.Instant
表示的是时间线上的一个瞬时点,总是相对于1970-01-01T00:00:00Z(UTC)的持续时间,类似Unix时间戳。。
在使用最新版MyBatis时,它已经支持了Java 8的日期时间API。这意味着无需手动配置TypeHandler,MyBatis能够自动处理这些类型的映射:
LocalDate
-> MySQLDATE
LocalTime
-> MySQLTIME
LocalDateTime
-> MySQLDATETIME
或TIMESTAMP
开发者在编写Mapper接口或者XML映射文件时,可以直接使用这些Java 8的日期时间类作为参数类型或结果类型,Mybatis会自动进行正确的数据类型转换。
原文链接:https://blog.csdn.net/qq_42651904/article/details/105049249