error java.time.format.DateTimeParseException: Text '2020-10-16T18:04:59+0300' could not be parsed at index 24

huangapple go评论71阅读模式
英文:

error java.time.format.DateTimeParseException: Text '2020-10-16T18:04:59+0300' could not be parsed at index 24

问题

我正在尝试使用LocalDateTime解析下面的字符串,但始终遇到未解析文本错误:

java.time.format.DateTimeParseException: 在索引 24 处无法解析文本 '2020-10-16T18:04:59+0300'

需求:从 2020-10-16T18:04:59+0300 得到 2020-10-16 18:04

我的代码:

public String getFormattingData(String sourceData) {
    DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ''e", Locale.ENGLISH);
    DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyy HH:mm", Locale.ENGLISH);
    LocalDate date = LocalDate.parse("2020-10-16T18:04:59+0300", sourceFormatter);
    return newFormatter.format(date);
}

我做错了什么?

英文:

I´m trying to pase the next String using LocalDateTime, but I always get de unparsed text found error:

java.time.format.DateTimeParseException: Text '2020-10-16T18:04:59+0300' could not be parsed at index 24

Need: from 2020-10-16T18:04:59+0300 to 2020-10-16 18:04.

My code:

    public String getFormattingData(String sourceData) {
        DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ''e", Locale.ENGLISH);
        DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyy HH:mm", Locale.ENGLISH);
        LocalDate date = LocalDate.parse("2020-10-16T18:04:59+0300", sourceFormatter);
        return newFormatter.format(date);
    }

What am I doing wrong?

答案1

得分: 2

参见相关问题:使用新的日期时间 API 格式化日期

  1. 你所寻找的源格式是:"yyyy-MM-dd'T'HH:mm:ssZ"(如@Sweeper在评论中所提到的)
  2. 如果你希望输出格式中包含HH:mm,你需要使用LocalDateTime而不是LocalDate

以下代码适用:

public String getFormattingData(String sourceData) {
    DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
    DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", Locale.ENGLISH);
    LocalDateTime date = LocalDateTime.parse("2020-10-16T18:04:59+0300", sourceFormatter);
    return newFormatter.format(date);
}

结果:

16-10-2020 18:04

英文:

See the related question: Format a date using the new date time API

  1. The source format you are looking for is: "yyyy-MM-dd'T'HH:mm:ssZ" (as mentioned by @Sweeper in his comment)
  2. If you want the HH:mm in the output format, you need to use a LocalDateTime rather than a LocalDate

The code below works for me:

public String getFormattingData(String sourceData) {
    DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
    DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", Locale.ENGLISH);
    LocalDateTime date = LocalDateTime.parse("2020-10-16T18:04:59+0300", sourceFormatter);
    return newFormatter.format(date);

result:

> 16-10-2020 18:04

答案2

得分: 1

你只需要纠正源日期的日期模式,如下所示:

public static String formatDate(String strDate, String srcPattern, String tgtPattern) {
  DateTimeFormatter srcFormatter = DateTimeFormatter.ofPattern(srcPattern, Locale.ENGLISH);
  DateTimeFormatter tgtFormatter = DateTimeFormatter.ofPattern(tgtPattern, Locale.ENGLISH);
  return tgtFormatter.format(LocalDateTime.parse(strDate, srcFormatter));
}

你还可以使用 SimpleDateFormat

public static String formatDate(String strDate, String srcPattern,
    String tgtPattern) throws ParseException {
  SimpleDateFormat srcFormatter = new SimpleDateFormat(srcPattern, Locale.ENGLISH);
  SimpleDateFormat tgtFormatter = new SimpleDateFormat(tgtPattern, Locale.ENGLISH);
  return tgtFormatter.format(srcFormatter.parse(strDate));
}

然后使用任何你想要的模式进行调用:

System.out.println(formatDate("2020-10-16T18:04:59+0300", "yyyy-MM-dd'T'HH:mm:ssZ", "dd-MM-yyyy HH:mm"));
英文:

You just need to correct the date pattern of source date like this:

public static String formatDate(String strDate, String srcPattern, String tgtPattern) {
  DateTimeFormatter srcFormatter = DateTimeFormatter.ofPattern(srcPattern, Locale.ENGLISH);
  DateTimeFormatter tgtFormatter = DateTimeFormatter.ofPattern(tgtPattern, Locale.ENGLISH);
  return tgtFormatter.format(LocalDateTime.parse(strDate, srcFormatter));
}

You can also use SimpleDateFormat:

public static String formatDate(String strDate, String srcPattern,
    String tgtPattern) throws ParseException {
  SimpleDateFormat srcFormatter = new SimpleDateFormat(srcPattern, Locale.ENGLISH);
  SimpleDateFormat tgtFormatter = new SimpleDateFormat(tgtPattern, Locale.ENGLISH);
  return tgtFormatter.format(srcFormatter.parse(strDate));
}

And then call it with any pattern that you want:

System.out.println(formatDate("2020-10-16T18:04:59+0300", "yyyy-MM-dd'T'HH:mm:ssZ", "dd-MM-yyy HH:mm"));

答案3

得分: 1

  1. 不要编写将日期和时间从一种格式的字符串转换为另一种格式字符串的方法。在您的程序中,将日期和时间保持为适当的日期时间对象,就像您不会将数字和布尔值保存在字符串中一样(我希望是这样的!)。当您收到字符串输入时,立即解析为日期时间对象。仅在需要生成字符串输出时,格式化为适当的字符串。

  2. 当我收到包含日期、时间和UTC偏移量的字符串(就像您的字符串一样)时,我更喜欢将其解析为OffsetDateTime,这样我可以获得所有信息。将不需要的信息稍后丢弃比发明我们忽略解析的信息要容易。而且LocalDate不适用于您的目的,因为它不包含每天的时间。因此,您无法将其格式化为2020-10-16 18:04的格式。

对于解析您的字符串,我会使用:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .append(DateTimeFormatter.ISO_LOCAL_DATE)
        .appendLiteral('T')
        .append(DateTimeFormatter.ISO_LOCAL_TIME)
        .appendOffset("+HHmm", "Z")
        .toFormatter();

String sourceData = "2020-10-16T18:04:59+0300";

OffsetDateTime dateTime = OffsetDateTime.parse(sourceData, formatter);

System.out.println(dateTime);

输出为:

> 2020-10-16T18:04:59+03:00

格式化器的定义有点长,但它具有重用日期和时间的预定义格式化器的优点。

对于向用户显示格式化的日期和时间,您不想使用用户的时区,而不是字符串中的偏移量(在您的情况下是+03:00)吗?

ZoneId zone = ZoneId.of("Antarctica/South_Pole");
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", Locale.ENGLISH);
String formatted = dateTime.atZoneSameInstant(zone).format(newFormatter);
System.out.println(formatted);

输出为:

> 17-10-2020 04:04

您的代码出了什么问题?

正如其他人所说,您用于解析的格式模式字符串中的yyyy-MM-dd'T'HH:mm:ssZ很好地解析了整个日期时间字符串2020-10-16T18:04:59+0300。格式模式字符串末尾的''e是问题所在。这将需要额外的单引号(撇号),并且星期几的数字必须出现(模式字母e用于本地化的星期几)。由于Java已经成功解析了前24个字符,然后在解析撇号时失败了,它抛出了异常,指出无法在索引24处解析字符串。

英文:
  1. Don’t write a method that converts a date and time from a string in one format to a string in a different format. In your program keep dates and times as proper date-time objects. Just like you don’t keep numbers and Boolean values in strings (I hope!) When you receive string input, parse into a date-time object at once. Only when you need to give string output, format into an appropriate string.
  2. When I receive a string containing date, time and UTC offset, like yours does, I prefer to parse it into a OffsetDateTime so I get all the information. It’s easier to throw unneeded information away later than to invent the information that we neglected to parse. Also a LocalDate will not work for your purpose since it doesn’t contain time of day. So you cannot format one into 2020-10-16 18:04 format.

For parsing your string I would use:

	DateTimeFormatter formatter = new DateTimeFormatterBuilder()
			.append(DateTimeFormatter.ISO_LOCAL_DATE)
			.appendLiteral('T')
			.append(DateTimeFormatter.ISO_LOCAL_TIME)
			.appendOffset("+HHmm", "Z")
			.toFormatter();
	
	String sourceData = "2020-10-16T18:04:59+0300";
	
	OffsetDateTime dateTime = OffsetDateTime.parse(sourceData, formatter);
	
	System.out.println(dateTime);

Output is:

> 2020-10-16T18:04:59+03:00

The definition of the formatter is longish but has the advantage of reusing predefined formatters for date and time.

For displaying a formatted date and time to the user, don’t you want to use the user’s time zone rather then the offset that happened to be in the string (+03:00 in your case)?

	ZoneId zone = ZoneId.of("Antarctica/South_Pole");
	DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", Locale.ENGLISH);
    String formatted = dateTime.atZoneSameInstant(zone).format(newFormatter);
    System.out.println(formatted);

> 17-10-2020 04:04

What went wrong in your code?

As others have said, yyyy-MM-dd'T'HH:mm:ssZ in your format pattern string for parsing parses your entire date-time string of 2020-10-16T18:04:59+0300 nicely. The ''e at the end of the format pattern is the culprit. This would require an additional single quote (apostrophe) and the number of the day of the week to be present (pattern letter e is for localized day of week). Since Java had successfully parsed 24 chars and then failed to parse an apostrophe, it threw the exception mentioning thst the string could not be parsed at index 24.

huangapple
  • 本文由 发表于 2020年10月17日 08:42:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/64398011.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定