解决报错Unsupported field: HourOfDay

本文讲述了在使用Java 8的时间日期API时遇到`UnsupportedTemporalTypeException: Unsupported field: HourOfDay`的报错,原因在于误用了`LocalDate`,正确的方法是使用`LocalDateTime`并解决了代码示例。

报错:Unsupported field: HourOfDay

这个错误就比较搞笑也比较低级了.

代码如下

LocalDate now = LocalDate.now();
String year = now.format(DateTimeFormatter.ofPattern("yyyy"));
String hour = now.format(DateTimeFormatter.ofPattern("MM-dd-HH"));

报错如下 

Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
    at java.time.LocalDate.get0(LocalDate.java:680)
    at java.time.LocalDate.getLong(LocalDate.java:659)
    at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
    at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2540)
    at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2179)
    at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1746)
    at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1720)
    at java.time.LocalDate.format(LocalDate.java:1691)
    at com.feiyangshop.recommendation.HdfsHandler.main(HdfsHandler.java:21)

我还追踪到了jdk源码中查看. 

private int get0(TemporalField field) {
        switch ((ChronoField) field) {
            case DAY_OF_WEEK: return getDayOfWeek().getValue();
            case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((day - 1) % 7) + 1;
            case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
            case DAY_OF_MONTH: return day;
            case DAY_OF_YEAR: return getDayOfYear();
            case EPOCH_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'EpochDay' for get() method, use getLong() instead");
            case ALIGNED_WEEK_OF_MONTH: return ((day - 1) / 7) + 1;
            case ALIGNED_WEEK_OF_YEAR: return ((getDayOfYear() - 1) / 7) + 1;
            case MONTH_OF_YEAR: return month;
            case PROLEPTIC_MONTH: throw new UnsupportedTemporalTypeException("Invalid field 'ProlepticMonth' for get() method, use getLong() instead");
            case YEAR_OF_ERA: return (year >= 1 ? year : 1 - year);
            case YEAR: return year;
            case ERA: return (year >= 1 ? 1 : 0);
        }
        throw new UnsupportedTemporalTypeException("Unsupported field: " + field);
    }

最后把异常抛出的代码在这.

说明我在now.format(DateTimeFormatter.ofPattern("MM-dd-HH"));HH是不在case之中的.

为什么case中只有年月日,没有小时和分秒呢?

emmmmm.

答案就是:我用错类了

应该使用LocalDateTime这个类.这个类包含时分秒.

LocalDateTime now = LocalDateTime.now();
String year = now.format(DateTimeFormatter.ofPattern("yyyy"));
String hour = now.format(DateTimeFormatter.ofPattern("MM-dd-HH"));
<think>我们正在解决Java中的`Unsupported field: HourOfDay`错误。根据引用,这个错误通常发生在尝试从一个不包含时间信息的日期对象(如`LocalDate`)中获取或格式化小时(HourOfDay)字段。 引用[2]指出:当使用`LocalDate.now().format(...)`并尝试格式化为包含小时、分钟或秒的格式(如"yyyy-MM-dd HH:mm:ss")时,因为`LocalDate`只包含日期(年、月、日),不包含时间,所以会抛出此异常。 引用[4]也提到:应该使用`LocalDateTime`类,因为它包含日期和时间(年、月、日、时、分、秒)。 因此,解决方案是:使用`LocalDateTime`代替`LocalDate`。 步骤: 1. 将代码中的`LocalDate`替换为`LocalDateTime`。 2. 使用`LocalDateTime.now()`获取当前日期和时间。 3. 然后使用`DateTimeFormatter`格式化为包含时间的字符串。 示例代码(正确): ```java import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class Main { public static void main(String[] args) { // 使用LocalDateTime而不是LocalDate LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedDateTime = now.format(formatter); System.out.println(formattedDateTime); } } ``` 错误示例(使用LocalDate): ```java import java.time.LocalDate; import java.time.format.DateTimeFormatter; public class Main { public static void main(String[] args) { // 错误:LocalDate没有时间信息 LocalDate now = LocalDate.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedDateTime = now.format(formatter); // 这里会抛出UnsupportedTemporalTypeException: Unsupported field: HourOfDay System.out.println(formattedDateTime); } } ``` 另外,引用[5]展示了一个转换:将Date对象转换为LocalDate,然后尝试格式化包含时间的模式也会出错。所以,如果要从Date对象转换,应该转换为LocalDateTime,而不是LocalDate。 总结: 错误原因:尝试格式化一个不包含时间字段的日期对象(如LocalDate)为包含时间部分的模式。 解决方法:使用包含时间信息的类(如LocalDateTime)来格式化。 注意:如果确实只需要日期部分,则应该使用只包含日期的模式(如"yyyy-MM-dd")。 引用来源:[^2][^4][^5] </think>### Java解决"Unsupported field: HourOfDay"错误的方法 该错误通常发生在**日期类型与格式化模式不匹配**的情况下。以下是根本原因和解决方案: #### 🚫 错误原因分析 1. **类型不匹配**: 试图从仅有日期信息的`LocalDate`(年月日)中提取时间信息(时分秒) ```java LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); // 错误! ``` `LocalDate`不包含时间字段,尝试访问`HourOfDay`字段时抛出异常[^2][^3] 2. **API误用**: 使用老旧的`Date`类配合新API时类型转换错误 ```java new Date().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); // 错误! ``` --- #### ✅ 解决方案(三种方法) ##### 方法1:使用正确的日期时间类 `LocalDateTime` ```java import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class FixExample { public static void main(String[] args) { // 使用包含时间的LocalDateTime类 LocalDateTime now = LocalDateTime.now(); // 创建格式化器 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 安全格式化(包含时间字段) System.out.println(now.format(formatter)); // 输出:2024-03-20 14:30:45 } } ``` ##### 方法2:转换 `Date` 到 `LocalDateTime` ```java import java.time.*; import java.util.Date; public class DateConversion { public static void main(String[] args) { Date oldDate = new Date(); // 正确转换路径:Date -> Instant -> ZonedDateTime -> LocalDateTime LocalDateTime correctDateTime = oldDate.toInstant() .atZone(ZoneId.systemDefault()) .toLocalDateTime(); // 关键步骤 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); System.out.println(correctDateTime.format(formatter)); } } ``` ##### 方法3:统一使用 `java.time` API(推荐) ```java // 避免混合使用新旧API ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Shanghai")); System.out.println(now.format(DateTimeFormatter .ofPattern("yyyy-MM-dd HH:mm:ss"))); ``` --- ### ⚠️ 关键注意事项 1. **类型选择原则**: | 需求 | 正确类 | 错误类 | |-------------------|---------------------|--------------| | 仅日期(年月日) | `LocalDate` | ❌ `LocalDateTime` | | 日期+时间 | `LocalDateTime` | ❌ `LocalDate` | | 带时区的日期时间 | `ZonedDateTime` | - | 2. **格式化模式匹配**: ```java // 安全组合 LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // ✅ // 危险组合(引发HourOfDay错误) LocalDate.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")); // ❌ ``` 3. **Jackson序列化特殊处理**: 如果出现在JSON序列化中(如引用[1]),添加模块支持: ```xml <!-- pom.xml --> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency> ``` ```java ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); // 关键配置 ``` --- > **根本原因**:Java的日期时间API被设计为**强类型系统**,每个类都有明确的语义边界。`LocalDate`物理上不包含时间字段数据,强制访问会破坏类型安全[^2][^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值