解析 localDateTime 时无法从 Temporal Accessor 获取 LocalDateTime。我正在努力摆脱不到 30 天的几个月

Posted

技术标签:

【中文标题】解析 localDateTime 时无法从 Temporal Accessor 获取 LocalDateTime。我正在努力摆脱不到 30 天的几个月【英文标题】:Unable to obtain LocalDateTime from Temporal Accessor when parsing localDateTime. I am trying to get rid of months less than 30days 【发布时间】:2021-08-25 17:50:17 【问题描述】:
DateTimeFormatter fm = new DateTimeFormatterBuilder()
            .appendPattern("MMMuuuu")
            .parseDefaulting(ChronoField.YEAR, 2021)
            .toFormatter(Locale.US);
         
          List<LocalDate> datesMoreThan30 = new ArrayList<>();
          List<LocalDate> datesLessThan30 = new ArrayList<>();
          String fromDate = from;
          String toDate = to;
         
          LocalDate date1 = LocalDate.parse(fromDate,fm);
          LocalDate date2 = LocalDate.parse(toDate,fm);
         
          long days = ChronoUnit.DAYS.between(date1, date2);
         
          if(days >= 30) 
                 datesMoreThan30.add(date1);
                 datesMoreThan30.add(date2);
                
          
          else if(days < 30) 
                 datesLessThan30.remove(date1);
                 datesLessThan30.remove(date2);
         
          

以下是我不断遇到的错误。

3:21:31.183 [http-nio-8088-exec-1] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.time.format.DateTimeParseException: Text 'Jan2021' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: MonthOfYear=1, Year=2021,ISO of type java.time.format.Parsed] with root cause
java.time.DateTimeException:

【问题讨论】:

你能展示一些输入输出的例子吗,对不起,我没有得到你的问题 为什么标题中会提到“localDateTime”? 【参考方案1】:

您使用ChronoField.YEAR 而不是ChronoField.DAY_OF_MONTH 代替DateTimeFormatterBuilder#parseDefaulting

带有正确ChronoField的演示:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Main 
    public static void main(String[] args) 
        DateTimeFormatter fm = new DateTimeFormatterBuilder()
                                .appendPattern("MMMuuuu")
                                .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                                .toFormatter(Locale.US);
        
        String fromDate = "Jan2021";
        LocalDate date1 = LocalDate.parse(fromDate, fm);
        System.out.println(date1);
    

输出:

2021-01-01

ONLINE DEMO

Trail: Date Time 了解有关现代日期时间 API 的更多信息。

【讨论】:

【参考方案2】:

日期由 3 个字段组成:YEARMONTH_OF_YEARDAY_OF_MONTH

您的模式要求文本具有 MONTH_OF_YEAR (MMM) 和 YEAR (uuuu),但没有日期值(ddd)。

由于未知的原因,你给了一个默认的YEAR,尽管模式需要一年,所以这个默认是没有意义的。你没有给出默认的DAY_OF_MONTH,所以没有足够的信息来建立一个日期。

解决方案 1

更改代码指定默认DAY_OF_MONTH

DateTimeFormatter fm = new DateTimeFormatterBuilder()
        .appendPattern("MMMuuuu")
        .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
        .toFormatter(Locale.US);

LocalDate date = LocalDate.parse("Jan2021", fm);
System.out.println(date); // 2021-01-01

解决方案 2

解析为 YearMonth,并在 Java 代码中提供 dayOfMonth:

DateTimeFormatter fm = DateTimeFormatter.ofPattern("MMMuuuu", Locale.US);

YearMonth ym = YearMonth.parse("Jan2021", fm);
LocalDate date = ym.atDay(1);
System.out.println(date); // 2021-01-01

【讨论】:

以上是关于解析 localDateTime 时无法从 Temporal Accessor 获取 LocalDateTime。我正在努力摆脱不到 30 天的几个月的主要内容,如果未能解决你的问题,请参考以下文章

使用杰克逊的 LocalDateTime 解析

Spring boot + Jackson + LocalDateTime:日期解析不正确

LocalDateTime 以数组格式表示

Java - LocalDateTime解析日期字符串值时丢弃秒值“00“,如“2021-07-01 15:33:00“ 转换为“2021-07-01T15:33“

Java - LocalDateTime解析日期字符串值时丢弃秒值“00“,如“2021-07-01 15:33:00“ 转换为“2021-07-01T15:33“

Java - LocalDateTime解析日期字符串值时丢弃秒值“00“,如“2021-07-01 15:33:00“ 转换为“2021-07-01T15:33“