Java:无法从 TemporalAccessor 获取 LocalDate

新手上路,请多包涵

I am trying to change the format of a String date from EEEE MMMM d to MM/d/yyyy by, first, converting it into a LocalDate and then在再次将其解析为 — LocalDate 之前,将不同模式的格式化程序应用于 String

这是我的代码:

 private String convertDate(String stringDate)
{
    //from EEEE MMMM d -> MM/dd/yyyy

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(DateTimeFormatter.ofPattern("EEEE MMMM d"))
            .toFormatter();

    LocalDate parsedDate = LocalDate.parse(stringDate, formatter);
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/d/yyyy");

    String formattedStringDate = parsedDate.format(formatter2);

    return formattedStringDate;
}

但是,我收到了我不太理解的异常消息:

 Exception in thread "main" java.time.format.DateTimeParseException: Text 'TUESDAY JULY 25' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {DayOfWeek=2, MonthOfYear=7, DayOfMonth=25},ISO of type java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)

原文由 user7049000 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

正如其他答案已经说过的,要创建一个 LocalDate 你需要 年份,它不在输入中 String 。它只有 daymonthday of the week

要获得完整的 LocalDate ,您需要解析 日期月份 并找到该 日期/月份 组合与 星期几 匹配的 年份

当然,您可以忽略 星期几,并假设日期始终是 当年;在这种情况下,其他答案已经提供了解决方案。但是如果你想找到与 星期几 完全匹配的 年份,你必须循环直到找到它。

我还创建了一个带有 java.util.Locale 的格式化程序,以明确表示我想要英文的 月份星期几 名称。如果您不指定语言环境,它将使用系统的默认设置,并且不能保证始终是英语(并且可以在不通知的情况下更改,即使在运行时也是如此)。

 DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .parseCaseInsensitive()
    .append(DateTimeFormatter.ofPattern("EEEE MMMM d"))
    // use English Locale to correctly parse month and day of week
    .toFormatter(Locale.ENGLISH);
// parse input
TemporalAccessor parsed = formatter.parse("TUESDAY JULY 25");
// get month and day
MonthDay md = MonthDay.from(parsed);
// get day of week
DayOfWeek dow = DayOfWeek.from(parsed);
LocalDate date;
// start with some arbitrary year, stop at some arbitrary value
for(int year = 2017; year > 1970; year--) {
    // get day and month at the year
    date = md.atYear(year);
    // check if the day of week is the same
    if (date.getDayOfWeek() == dow) {
        // found: 'date' is the correct LocalDate
        break;
    }
}

在此示例中,我从 2017 年开始并试图找到一个可以追溯到 1970 年的日期,但您可以调整适合您的用例的值。

您还可以使用 Year.now().getValue() 获取当前年份(而不是某个固定的任意值)。

原文由 user7605325 发布,翻译遵循 CC BY-SA 3.0 许可协议

LocalDate 的文档说,

LocalDate 是一个不可变的日期时间对象,表示一个日期,通常被视为年月日。例如,值“2007 年 10 月 2 日”可以存储在 LocalDate 中。

在您的情况下,输入 String 缺少 LocalDate 的重要组成部分,即年份。你所拥有的基本上是月份和日期。因此,您可以使用适合该类的类 MonthDay 。使用你的代码可以修改为:

 DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .append(DateTimeFormatter.ofPattern("EEEE MMMM d"))
                .toFormatter();

 MonthDay monthDay = MonthDay.parse(stringDate, formatter);
 LocalDate parsedDate = monthDay.atYear(2017); // or whatever year you want it at
 DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/d/yyyy");

 String formattedStringDate = parsedDate.format(formatter2);
 System.out.println(formattedStringDate); //For "TUESDAY JULY 25" input, it gives the output 07/25/2017

原文由 Pallavi Sonal 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题