无法使用DateTimeFormatter

时间:2019-05-21 16:34:46

标签: java date date-parsing java.time

我尝试查看此链接以获取灵感:Parsing a date’s ordinal indicator ( st, nd, rd, th ) in a date-time string

但是,当我尝试将字符串“ 5月21日星期一”解析为“ 5月21日星期一”时,出现了错误-全天名称,日期编号和整月。

  

线程“ main”中的异常java.time.format.DateTimeParseException:   无法在索引0处解析文本“ 5月21日星期一”   java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)     在   java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)     在java.time.LocalDate.parse(LocalDate.java:400)在   HelloWorld.main(HelloWorld.java:45)

代码如下:

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.Locale;

// one class needs to have a main() method
public class HelloWorld
{
  // arguments are passed using the text field below this editor
  public static void main(String[] args) throws Exception
  {

    String str = "Mon 21st May";
    DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEEE d['st']['nd']['rd']['th'] MMMM", Locale.ENGLISH);
    LocalDate datetext = LocalDate.parse(str, parseFormatter);

  }
}

更新:

这是我尝试按照建议操作的最新代码,我更改了字符串以查看问题是否与该问题有关,并且下面是我现在收到的错误。看起来它知道日期,只是无法解析:

  public static void main(String[] args) throws Exception
  {

    String str = "Tue 21st May";
    DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEE d['st']['nd']['rd']['th'] MMMM", Locale.ENGLISH);
    LocalDate datetext = LocalDate.parse(str, parseFormatter);

  }
}

错误:

  

线程“ main”中的异常java.time.format.DateTimeParseException:   无法解析文字“ 5月21日星期二”:无法从中获取LocalDate   TemporalAccessor:{DayOfWeek = 2,DayOfMonth = 21,MonthOfYear = 5},ISO为   键入java.time.format.Parsed在   java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)     在   java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)     在java.time.LocalDate.parse(LocalDate.java:400)在   HelloWorld.main(HelloWorld.java:26)由以下原因引起:   java.time.DateTimeException:无法从中获取LocalDate   TemporalAccessor:{DayOfWeek = 2,DayOfMonth = 21,MonthOfYear = 5},ISO为   键入java.time.format.Parsed在   java.time.LocalDate.from(LocalDate.java:368)在   java.time.format.Parsed.query(Parsed.java:226)在   java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)     ...还有2个

3 个答案:

答案 0 :(得分:4)

MonthDay

如果您要解析不带年份的月份和月份,请使用MonthDay

    String str = "Mon 21st May";
    DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEE d['st']['nd']['rd']['th'] MMMM", Locale.ENGLISH);
    MonthDay md = MonthDay.parse(str, parseFormatter);
    System.out.println(md);

输出为:

  

-05-21

前导破折号表示缺席年份。格式模式字符串中的EEEE用于表示星期几的全名,例如星期一或星期二。对于缩写,您需要EEEEEE

LocalDate

如果您想要LocalDate,则需要以某种方式提供一年。一种选择是:

    LocalDate datetext = md.atYear(Year.now(ZoneId.of("Europe/London")).getValue());
    System.out.println(datetext);
  

2019-05-21

但是,这不会验证每月的某天。为此:

    String str = "Tue 21st May";
    DateTimeFormatter parseFormatter = new DateTimeFormatterBuilder()
            .appendPattern("EEE d['st']['nd']['rd']['th'] MMMM")
            .parseDefaulting(ChronoField.YEAR, Year.now(ZoneId.of("Europe/London")).getValue())
            .toFormatter(Locale.ENGLISH);

    LocalDate datetext = LocalDate.parse(str, parseFormatter);
  

2019-05-21

在您询问的评论中:

  

如果我想在5月21日星期二输出,该怎么办?

这是一个新问题,已经讨论了很多次,但是可以。

    DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("EEEE d MMMM", Locale.ENGLISH);
    System.out.println(datetext.format(outputFormatter));
  

5月21日星期二

从星期几起检测年份

  

我可能不知道年份,因为我正在尝试查看日期   申请,但某些日期可能是今年,有些可能会落到   明年,但这些日期没有提供年份

以下完整示例假定日期在从今天起的未来三年内,并检测星期几正确的年份。成功后,它将以您想要的格式打印。

    String str = "Wed 20th May";
    ZoneId zone = ZoneId.of("Europe/London");
    LocalDate today = LocalDate.now(zone);
    int currentYear = today.getYear();
    LocalDate datetext = null;
    final int maxYearsFromToday = 3;
    for (int year = currentYear; year <= currentYear + maxYearsFromToday; year++) {
        DateTimeFormatter parseFormatter = new DateTimeFormatterBuilder()
                .appendPattern("EEE d['st']['nd']['rd']['th'] MMMM")
                .parseDefaulting(ChronoField.YEAR, year)
                .toFormatter(Locale.ENGLISH);

        try {
            datetext = LocalDate.parse(str, parseFormatter);
            System.out.println("Day of week matched for year " + year);
            break;
        } catch (DateTimeParseException dtpe) {
            // Ignore, try next year
        }
    }

    DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("EEEE d MMMM", Locale.ENGLISH);
    if (datetext == null) {
        System.out.println("Could not parse date;"
                + " possibly the day of week didn’t match for any year in the range "
                + currentYear + " through " + (currentYear + maxYearsFromToday));
    } else if (datetext.isBefore(today) || datetext.isAfter(today.plusYears(maxYearsFromToday))) {
        System.out.println("Date is out of range");
    } else {
        System.out.println("Successfully parsed: " + datetext.format(outputFormatter));
    }
Day of week matched for year 2020
Successfully parsed: Wednesday 20 May

答案 1 :(得分:1)

今天星期二。以下代码有效。

    String str = "Tue 21st May 2019";
    DateTimeFormatter parseFormatter = DateTimeFormatter.ofPattern("EEE d['st']['nd']['rd']['th'] MMMM yyyy", Locale.ENGLISH);
    LocalDate datetext = LocalDate.parse(str, parseFormatter);

答案 2 :(得分:0)

这是我搜索正确年份的代码:

在不知道星期几的情况下,您有6/7的机会将日期解析为错误的年份。但是,如果您知道日期名称,则可以搜索7年范围以找到正确的年份。

假设您有以下任一日期:

{
    "cues": "PLC2hrOGTT",
    "directions": ">",
    "thresholds": "126",
    "exits": "1",
    "children": [
      {
        "cues": "True",
      },
      {
        "cues": "Age",
        "directions": ">",
        "thresholds": "29",
        "exits": "0",
        "children": [
          {
            "cues": "BMI",
            "directions": ">",
            "thresholds": "29.7",
            "exits": "1",
            "children": [
              {
                "cues": "True",
              },
              {
                "cues": "TimesPregnant",
                "directions": ">",
                "thresholds": "6",
                "exits": "0.5",
                "children":[
                  {
                    "cues": "True"
                  },
                  {
                    "cues": "False"
                  }
                ]
              }
            ]
          },
          {
            "cues": "False"
          }
        ]
      }
    ]
    }

格式化程序如下:

Wednesday, May 27
WED 5/27

然后,您可以像这样解析MonthDay:

DateTimeFormatter visibleButtonFormat = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("EEE M/dd")
            .toFormatter(Locale.US);
        DateTimeFormatter accessibleFormat = DateTimeFormatter.ofPattern("EEEE, MMMM dd");

然后,您可以搜索正确的年份。在这种情况下是2020年:

MonthDay monthDay = MonthDay.parse(dateText, oneOfTheAboveFormatters);