无法解析日期异常



我在字符串类型上有日期和时间20/03/2018, 18:20:44是否可以在 java 中将其更改为日期格式?我尝试了以下代码:

public static Date getDate(String dateString) {
DateFormat formatter = new SimpleDateFormat("dd/mm/yyyy hh:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("PST"));
try {
Date date = formatter.parse(dateString);
return date;
} catch (ParseException e) {
logger.error("error while parsing milliseconds to date" + dateString, e);
}
return null;
}

我无法解析异常并返回空

您在简单的日期格式中使用了错误的字符串替换,它应该是dd/MM/yyyy, HH:mm:ss.还要注意 HH 的大写,您的时间是 24 小时格式,因此必须HH超过hh

因此,通过应用的更改,您的代码将如下所示:

public static Date getDate(String dateString) {
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy, HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("PST"));
try {
return formatter.parse(dateString);
} catch (ParseException e) {
logger.error("error while parsing milliseconds to date" + dateString, e);
}
return null;
}

在此处阅读有关各种模式的更多信息,因为通常建议对日期使用 ISO 8601 格式,这样您的日期就会yyyy-MM-ddTHH:mm:ss

您应该对输入字符串使用相同的格式:

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy, hh:mm:ss");

你犯了两个错误:

  • mm表示分钟。MM代表月份。
    但是,您可以在日期格式的月份部分中指定mm
  • 输入中提供的逗号字符 :,也必须以日期格式存在。

因此,对于以下形式的字符串输入:"20/03/2018, 18:20:44",您应该使用此DateFormat:

DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy, hh:mm:ss");

tl;博士

您的格式模式不正确,使用了错误的大小写并省略了逗号。

此外,您正在使用几年前被java.time类取代的麻烦类。

LocalDateTime.parse(                                       // Create a `LocalDateTime` object as the input string lacks any time zone or offset-from-UTC.
"20/03/2018, 18:20:44" , 
DateTimeFormatter.ofPattern( "dd/MM/uuuu, HH:mm:ss" )  // Define a formatting pattern to match the input.
)
.atZone(                                                   // Assign a time zone to the `LocalDateTime` to create a `ZonedDateTime` object.
ZoneId.of( "America/Los_Angeles" )                     // Specify time zone to be assigned. Always use proper zone names `continent/region`; never use 3-4 character pseudo-zones.
)

2018-03-20T18:20:44-07:00[美国/Los_Angeles]

java.time

您正在使用麻烦的旧日期时间类,这些类现在是遗留的,被java.time类所取代。

将字符串解析为LocalDateTime,因为它缺少时区或 UTC 偏移量的指示符。

String input = "20/03/2018, 18:20:44" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu, HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

ldt.toString(): 2018-03-20T18:20:44

缺少时区或与 UTC 的偏移量意味着这代表某个时刻,不是时间轴上的一个点。如果没有区域/偏移的上下文,这仅代表关于 26-27 小时内潜在时刻的模糊概念。

显然,您确定此输入实际上应该位于某个时区。将ZoneId应用于此LocalDateTime以获取ZonedDateTime对象。

continent/region的格式指定正确的时区名称,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Los_Angeles" ) ; 
ZonedDateTime zdt = ldt.atZone( z ) ;

转换

最好避免麻烦的遗留类。但是,如果必须生成一个java.util.Date才能与尚未针对java.time更新的旧代码进行互操作,则可以进行转换。若要来回转换,请在旧类上调用新方法。

java.util.Date表示时间轴上的一个点(以 UTC 为单位),分辨率为毫秒。所以它在java.time中的替换是InstantInstant也是时间轴上的一个点,采用 UTC 格式,分辨率更精细,为纳秒。为了得到一个Date,我们需要一个Instant,我们可以从我们的ZonedDateTime中提取它。

Instant instant = zdt.toInstant() ;  // Same moment, same point on the timeline, different wall-clock time.

现在我们可以通过调用Date.from来获取 legacy 类对象Date

java.util.Date date = Date.from( instant ) ;  // Do this only if you *must* work with `Date` class.

关于java.time

java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅Oracle 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。

您可以直接与数据库交换java.time对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要java.sql.*类。

从哪里获得java.time类?

Java SE
  • 8Java SE 9及更高版本
    • 内置。
    • 具有捆绑实现的标准 Java API 的一部分。
    • Java 9添加了一些小功能和修复。
  • Java SE 6 和 Java SE 7 大部分
    • java.time 功能在ThreeTen-Backport中向后移植到 Java 6 和 7。
  • Android
    • 更高版本的 java.time 类的 Android 捆绑实现。
    • 对于早期的Android(<26),ThreeTenABP项目适应了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP...

ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等。

最新更新