【Java.Core】Java Date Time 教程

本文对比了Java8与Java7的日期时间API,详细介绍了Java8中引入的全新API及其核心类,包括Instant、Duration、LocalDate、LocalDateTime、LocalTime、ZonedDateTime等,并解释了它们在时间表示、持续时间、日期与时间处理等方面的区别。同时,文章还总结了如何选择合适的类进行简单的时间设置、日期加载、日期时间读写、日期计算以及时区转换等操作。

转自Java Date Time 教程

原文链接 作者:Jakob Jenkov  译者:魏嘉鹏

目录

  • Java 8 Date Time API
  • Java 7 Date Time API

当你初次尝试弄明白怎么去使用Java的date time 的API的时候,那是相当令人困惑的。Therefore I have put together this little trail on Java’s date and time classes。希望这会让你对Java’的date类和time类有个总体的认识。我也希望这能消除一些Sun所制造的关于Java中许多date和time类的困惑。
实际上,在Java8中,随着一整套新的类的引入,旧有的date time API已经发生了改变(清除)。这个教程将会一起解释Java8和Java7的date time API.

Java 8 Date Time API

在Java8中,加入了一个全新的date time API。这个API在Java8标准类库中的java.time包。
Java8中date time API最主要的改变是日期和时间不再表示为从1970年1月1日到现在为止的总毫秒数,而是总秒数和总纳秒数。总秒数可以是正的也可以是负的以及它由long类型来表示。总纳秒数永远是正的以及它由int类型来表示。你将会在新的Java date time API 的许多类中看到这种新的日期和时间表现形式。
Java.time 包中也包含了一套子类,这些子类包含了更多的实用工具等。举个例子,java.time.chrono包中包含了一些处理日本、泰国、台湾和伊斯兰日历的对象类。Java.time.format包中包含了用于转换strings到dates和格式化 dates 到 strings。

Java8 中date time API核心由以下这些类组成:

Instant表示时间线上的一个瞬间。在Java7的date time API中,一个瞬间通常由从1970年1月1日到现在的总毫秒数来表示。在Java8中Instant类代表着时间线上的一个瞬间,这个瞬间由从1970年1月1日到现在的总秒数和总纳秒数来表示。
Duration表示持续的时间,比如在两个瞬间之间的时间。和Instant类一样,Duration将这个时间表示为总秒数和总纳秒数。
LocalDate表示不带时区信息的日期-比如生日日期、官方节日等。
LocalDateTime表示不带时区信息的日期时间。
LocalTime表示不带时区信息的当地时间。
TemporalAdjuster译者注:原文这里为空白)
ZonedDateTime表示携带时区信息的日期时间
Period译者注:原文这里为空白)
DateTimeFormatter将date time对象格式化为字符串。比如zonedDateTime或者LocalDateTime。

Java 7 Date Time API

Java7有以下日期时间的类和方法。后面我会在每一个类的各自的页面介绍他们。

System.currentTimeMillis()将从1970年1月1日到当前时间的总毫秒数返回的静态方法。
java.util.Date表示日期和时间的类,其中大部分方法已被弃用。
java.sql.Date表示日期的类。去除了所有时间信息。该类由JDBC所使用。
java.sql.Timestamp表示日期和时间的类。该类由JDBC所使用。
java.util.Calendar一些Calendar类的基类,拥有着计算日期和时间的方法,比如在另一个日期上添加一天或者一个月。
java.util.GregorianCalendarjava.util.Calendar的一个具体子类,表示在当今西方普遍使用的公历。拥有着来自于 java.util.Calendar所有计算日期和时间的方法。
java.util.TimeZoneJava TimeZone类表示时区,在跨时区的日历计算很有用。
java.text.SimpleDateFormat该类可以帮助你转换strings到dates和格式化 dates 到 strings。

那么,哪些类是你应该使用的呢?这个取决于你将要做什么。
如果你只是做一些简单的时间设置,那么System.currentTimeMillis()就足矣。
如果你只是需要一个能够装载日期的对象,比如作为一个简单的域模型对象的属性,那么你可以使用java.util.Date 类。
如果你只是需要读取和写入日期时间到数据库,那么使用java.sql.Date 类和java.sql.Timestamp类。
如果你只是需要做一些日期计算,比如在另一个日期添加一些天数或者月数、检查给定的日期是一周中的第几天(周一、周二等)、在时区之间转换日期和时间,那么使用java.util.Calendar类和java.util.GregorianCalendar 类。
这里有一个Java date 和time 教程的列表,方便你快速导航(译者注:目前还没有翻译完,会尽快补全):

(全文完)


在 Spring 中,将 `java.lang.String` 转换为 `java.util.Date` 失败,报错 `ConversionFailedException` 和 `IllegalArgumentException` ,通常是由于日期格式不匹配或者缺少合适的转换器导致的。以下是几种常见的解决办法: ### 使用 `@DateTimeFormat` 注解 在实体类的日期属性上使用 `@DateTimeFormat` 注解指定日期格式。示例代码如下: ```java import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; public class YourEntity { @DateTimeFormat(pattern = "yyyy-MM-dd") private Date createdTime; // Getters and Setters public Date getCreatedTime() { return createdTime; } public void setCreatedTime(Date createdTime) { this.createdTime = createdTime; } } ``` 这样,Spring 在进行数据绑定的时候,会按照指定的格式进行转换。 ### 自定义转换器 可以通过实现 `org.springframework.core.convert.converter.Converter` 接口来创建自定义的日期转换器。示例代码如下: ```java import org.springframework.core.convert.converter.Converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class StringToDateConverter implements Converter<String, Date> { private static final String DATE_FORMAT = "yyyy-MM-dd"; @Override public Date convert(String source) { try { return new SimpleDateFormat(DATE_FORMAT).parse(source); } catch (ParseException e) { throw new IllegalArgumentException("Invalid date format. Please use yyyy-MM-dd."); } } } ``` 然后在配置类中注册这个转换器: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.format.support.FormattingConversionServiceFactoryBean; import java.util.HashSet; import java.util.Set; @Configuration public class ConversionConfig { @Bean public FormattingConversionServiceFactoryBean conversionService() { FormattingConversionServiceFactoryBean factory = new FormattingConversionServiceFactoryBean(); Set<Converter<?, ?>> converters = new HashSet<>(); converters.add(new StringToDateConverter()); factory.setConverters(converters); return factory; } } ``` ### 全局日期格式化配置 可以在配置类中使用 `WebMvcConfigurer` 接口的 `addFormatters` 方法进行全局日期格式化配置。示例代码如下: ```java import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.text.SimpleDateFormat; import java.util.Date; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new Converter<String, Date>() { @Override public Date convert(String source) { try { return new SimpleDateFormat("yyyy-MM-dd").parse(source); } catch (Exception e) { return null; } } }); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值