首页 > 解决方案 > 如何使用日期格式 yyyy-MM-dd hh:mm a 在 Java 8 中解决不可解析的日期异常

问题描述

我有一个文本文件,我正在从中读取和设置事务 POJO 类数据,以获取开始时间和结束时间之间的差异,我需要解析日期对象中的时间信息。

DateFormat format = new SimpleDateFormat(dateFormat);
System.out.println("Date format in play:"+dateFormat);
Transaction transaction = storageRepositroy.getTransaction(key);
Date start = format.parse(transaction.getStartDate() + " " + transaction.getStartTime());//line no. 29
Date end = format.parse(transaction.getEndDate() + " " + transaction.getEndTime());

运行此代码时出现异常

例外是

Date format in play:yyyy-MM-dd hh:mm a
java.text.ParseException: Unparseable date: "2020–03–01 03:15 PM"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at dc.tech.transaction.util.TimeUtil.calculateAverageTime(TimeUtil.java:29)

yyyy-MM-dd hh:mm a 是我传递给 SimleDateFormat 构造函数的日期格式。我无法理解和调试为什么会收到此错误。

标签: javadatesimpledateformat

解决方案


java.time

我建议您使用现代 Java 日期和时间 API java.time 进行日期和时间工作。

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu\u2013MM\u2013dd");
    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
    
    String dateString = "2020–03–01";
    String timeString = "03:15 PM";
    
    LocalDate date = LocalDate.parse(dateString, dateFormatter);
    LocalTime time = LocalTime.parse(timeString, timeFormatter);
    LocalDateTime dateTime = date.atTime(time);
    
    System.out.println(dateTime);

输出:

2020-03-01T15:15

使用 java.time 可以直接在解析后组合日期和时间,因此我更喜欢单独解析它们。

你的代码出了什么问题?

感谢 Ajeetkumar 在评论中注意到和报告:日期字符串中的连字符不是通常的减号或字符值 2D 十六进制(十进制 45)的连字符,而是字符值 2013 十六进制(十进制 8211)的短划线。因此,当您在格式模式字符串中指定常用连字符时,它们不匹配,并且解析失败。相反,我使用 Unicode 转义将破折号放入格式模式字符串中。只需将其粘贴到那里也可以(前提是您使用支持它的字符编码保存 .java 文件),但我想让读者知道这里发生了一些特别的事情,所以我更喜欢使用 Unicode 转义\u.

您的代码还有另一个问题:您没有为格式化程序提供任何语言环境。因此它使用 JVM 的默认语言环境。只要该语言环境期望PM,解析就会起作用。如果有一天您更改了语言环境设置或在具有不同默认语言环境的计算机或 JVM 上运行代码,解析将突然失败,您可能很难找出原因。我已经指定了英语语言环境来解析时间。有些人也更喜欢在约会时这样做,即使技术上没有必要。

链接


推荐阅读