如何使用日期格式 yyyy-MM-dd hh:mm a 解决 Java 8 中无法解析的日期异常
How to resolve Unparseable date Exception in Java 8 with Date format yyyy-MM-dd hh:mm a
我有一个文本文件,我正在从中读取和设置事务 POJO class 数据,为了获得开始时间和结束时间之间的差异,我需要解析日期对象中的时间信息。
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 构造函数的日期格式。我无法理解和调试为什么会出现此错误。
java.time
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。
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 十进制)的连字符,而是 en dash 字符值为 2013 十六进制(8211 十进制)。因此,当您在格式模式字符串中指定一个常用的连字符时,它们不匹配,并且解析失败。相反,我使用 Unicode 转义符将破折号放入格式模式字符串中。简单地将它粘贴到那里也可以工作(前提是你用支持它的字符编码保存你的 .java 文件),但我想让 reader 意识到这里发生了一些特别的事情,所以我更喜欢使用 \u
.
的 Unicode 转义
您的代码还有另一个问题:您没有为格式化程序提供任何语言环境。所以它使用 JVM 的默认语言环境。只要该语言环境需要 PM
,解析就会起作用。如果有一天您更改了语言环境设置或 运行 您在具有不同默认语言环境的计算机或 JVM 上的代码,解析将突然失败,您可能很难找出原因。我已经指定了英语语言环境来解析时间。有些人更喜欢在约会时这样做,尽管从技术上讲这不是必需的。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Unicode Character 'EN DASH' (U+2013) FileFormat.info。
我一直坚持这个原则: 使用与 date-time 字符串完全相同的格式。
在下面给出的解决方案中,我已将您的 date-time 字符串复制到我为 SimpleDateFormat
和 DateTimeFormatter
指定的模式中,并将数字替换为相应的字母,例如2020
与 yyyy
同时保持其余部分(符号、space 等)完整无缺。
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
DateFormat sdf = new SimpleDateFormat("yyyy–MM–dd hh:mm a", Locale.ENGLISH);// Make sure to use Locale
String dateTimeString = "2020–03–01 03:15 PM";// The string copied from the exception you have got
Date date = sdf.parse(dateTimeString);
System.out.println(sdf.format(date));
}
}
输出:
2020–03–01 03:15 PM
注:java.util
的date-timeAPI及其格式API、SimpleDateFormat
已过时和 error-prone。我建议你应该完全停止使用它们并切换到 modern date-time API.
使用现代date-time API:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy–MM–dd hh:mm a", Locale.ENGLISH);// Make sure to use Locale
String dateTimeString = "2020–03–01 03:15 PM";// The string copied from the exception you have got
System.out.println(LocalDateTime.parse(dateTimeString, dtf));
}
}
输出:
2020-03-01T15:15
了解有关现代 date-time API 的更多信息
如果您正在为您的 Android 项目执行此操作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and .
我有一个文本文件,我正在从中读取和设置事务 POJO class 数据,为了获得开始时间和结束时间之间的差异,我需要解析日期对象中的时间信息。
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 构造函数的日期格式。我无法理解和调试为什么会出现此错误。
java.time
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。
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 十进制)的连字符,而是 en dash 字符值为 2013 十六进制(8211 十进制)。因此,当您在格式模式字符串中指定一个常用的连字符时,它们不匹配,并且解析失败。相反,我使用 Unicode 转义符将破折号放入格式模式字符串中。简单地将它粘贴到那里也可以工作(前提是你用支持它的字符编码保存你的 .java 文件),但我想让 reader 意识到这里发生了一些特别的事情,所以我更喜欢使用 \u
.
您的代码还有另一个问题:您没有为格式化程序提供任何语言环境。所以它使用 JVM 的默认语言环境。只要该语言环境需要 PM
,解析就会起作用。如果有一天您更改了语言环境设置或 运行 您在具有不同默认语言环境的计算机或 JVM 上的代码,解析将突然失败,您可能很难找出原因。我已经指定了英语语言环境来解析时间。有些人更喜欢在约会时这样做,尽管从技术上讲这不是必需的。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Unicode Character 'EN DASH' (U+2013) FileFormat.info。
我一直坚持这个原则: 使用与 date-time 字符串完全相同的格式。
在下面给出的解决方案中,我已将您的 date-time 字符串复制到我为 SimpleDateFormat
和 DateTimeFormatter
指定的模式中,并将数字替换为相应的字母,例如2020
与 yyyy
同时保持其余部分(符号、space 等)完整无缺。
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
DateFormat sdf = new SimpleDateFormat("yyyy–MM–dd hh:mm a", Locale.ENGLISH);// Make sure to use Locale
String dateTimeString = "2020–03–01 03:15 PM";// The string copied from the exception you have got
Date date = sdf.parse(dateTimeString);
System.out.println(sdf.format(date));
}
}
输出:
2020–03–01 03:15 PM
注:java.util
的date-timeAPI及其格式API、SimpleDateFormat
已过时和 error-prone。我建议你应该完全停止使用它们并切换到 modern date-time API.
使用现代date-time API:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy–MM–dd hh:mm a", Locale.ENGLISH);// Make sure to use Locale
String dateTimeString = "2020–03–01 03:15 PM";// The string copied from the exception you have got
System.out.println(LocalDateTime.parse(dateTimeString, dtf));
}
}
输出:
2020-03-01T15:15
了解有关现代 date-time API 的更多信息
如果您正在为您的 Android 项目执行此操作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and