当前位置: 首页 > 知识库问答 >
问题:

无法解析文本,找到未解析文本

龚凯泽
2023-03-14

我无法理解为什么当我通过的文本符合格式时,我会得到DateTimeParseException错误。下面是导致该问题的代码:

LocalTime lt = LocalTime.parse(songTime, 
DateTimeFormatter.ofPattern("k:m:s"));

奇怪的是。每当我查询用户一段时间(让我们以00:02:30为例),它就会完全按照我想要的方式运行。但是当我使用我的方法(从文本文件中提取时间)时,它会出现错误:

线程“main”java.time.format.DateTimeParseException中出现异常:无法分析文本“00:02:30”,在索引8中找到未分析的文本

00:00:00 First
00:02:30 Second

第一次顺利通过,但之后的任何人都会导致错误。它们都有完全相同的格式,两边都没有空格,所以我看不出问题所在。我检查了关于这个问题的每一个论坛帖子,大多数都是使用错误格式、错误字符串等的个人。我不确定这是这里的情况,因为当我硬编码或查询用户输入时,它可以完美地工作。

下面是我在格式化程序中(从文档中)选择的每个选项的含义:

k       clock-hour-of-am-pm (1-24)
m       minute-of-hour 
s       second-of-minute

下面是读取文件的方法:

public static ArrayList<Song> scanInSongs () {

ArrayList<Song> songArray = new ArrayList<Song>();

try { 

    BufferedReader reader = new BufferedReader(new FileReader("Description.txt"));
    String line;

    while ((line = reader.readLine()) != null) {
       String key = line.substring(0, line.indexOf(' '));
       System.out.println("Fetched timestamp: "+ key);
       String value = line.substring(line.indexOf(' ') + 1);
       System.out.println("Fetched name: "+ value);

       Song song = new Song(value, "", key);
       songArray.add(song);
    }
} catch (IOException e) {
    System.out.println("File not found, exception: "+ e);
} 

return songArray;
public class Song {
    private String duration = "";
    private String name = "";
    private String timestampFromVideo = "";

    public Song(String name, String timestampFromVideo, String duration) {
        if (name == "") {
            this.name = "";   
        } else {
            this.name = name;
        }
        this.duration = duration;

        this.timestampFromVideo = timestampFromVideo;
    }

    public String getName() {
        return this.name;
    }

    public String getDuration() {
        return this.duration;
    }

    public String getTimestampFromVideo() {
        return this.timestampFromVideo;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

}
public static void main(String[] args) {

    ArrayList<Song> songArray = scanInSongs();

    String songTime = songArray.get(0).getDuration();

    LocalTime lt = LocalTime.parse(songTime, 
    DateTimeFormatter.ofPattern("k:m:s"));       
}
00:00:00 First
00:02:30 Second

提前感谢大家的帮助!

共有1个答案

贝德辉
2023-03-14

您的字符串中有一个非打印字符(所以没有空白,因为strip()没有帮助)。由于字符串已从文件中读取,因此该字符必须在文件中。

如何检查:

    key.chars().forEach(System.out::println);

如果只是“00:02:30”,则会打印

48
48
58
48
50
58
51
48
48
48
58
48
50
58
51
48
8203

好的解决办法是从文件中删除字符。

我完全同意Arvind Kumar Avinash的回答:您应该使用duration类一段时间(如果有一天遇到超过24小时的持续时间,LocalTime也将不再工作)。您应该进一步使用duration,并且在您的模型类中将duration保持为duration,而不是字符串。就像您将数字保存在int变量中,而不是字符串中一样(我非常希望)。

public class Song {
    private Duration duration;
    private String name;
    // …

因为您的实例变量总是从构造函数初始化的,所以不要在声明中给它们默认值,那样只会混淆。您可以编写一个方便的构造函数,将字符串解析为持续时间,例如:

/** @throws DateTimeParseException if durationString is not in format hh:mm:ss */
public Song(String name, String timestampFromVideo, String durationString) {
    this.name = "";   
    String iso = durationString.replaceFirst(
            "^(\\d{2}):(\\d{2}):(\\d{2})$", "PT$1H$2M$3S");
    duration = Duration.parse(iso);
    String iso = durationString.replaceFirst(
            "^(\\d{2}):(\\d{2}):(\\d{2}).*$", "PT$1H$2M$3S");

我在表示字符串结尾的$之前插入了.*。这将匹配可能存在的任何字符,并导致它们不进入ISO 8601字符串。所以现在解析也可以在文件中有零宽度的空格时工作。

此外,如果使用duration,Arvind也是正确的,如果要解析为localtime,则不需要DateTimeFormatter,因为00:02:30在一天中的某个时间是ISO 8601格式,并且localtime解析此格式时不指定格式化程序。最后,Joachim Isaksson的注释是正确的,即模式字母k在一天中的几个小时内为0时是不正确的。k表示一天中的时钟-小时(1-24)。对于一天中的一个小时(00-23),您需要hh

  • fileformat.info上的Unicode字符“零宽度空格”(U+200B)(重复您自己的链接)
  • 持续时间
  • 的文档
  • 维基百科文章:ISO 8601
 类似资料: