Java:SimpleDateFormat - 无法将字符串解析为所需格式的日期

时间:2012-03-05 08:42:40

标签: java simpledateformat java.util.date

我正在尝试将一个字符串解析为yyyy-MM-dd格式,将一个字符串解析为yyyy-MM-dd HH:mm:ss。 我正在使用SimpleDateFormat

我之前已成功使用过相同的方法,但现在出现了问题。我以标准格式获取日期,即Tue Mar 05 00:00:00 GMT+05:30 2012(对于yyyy-MM-dd)和Mon Mar 05 13:01:35 GMT+05:30 2012(对于yyyy-MM-dd HH:mm:ss),因为我需要它们2012-03-05和{ {1}}分别。

这就是我的所作所为:

2012-03-05 13:01:35

Date today = new Date();
SimpleDateFormat tsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
    today = tsdf.parse(tsdf.format(new Date()));
} catch(Exception e) {
    System.out.println("Error occurred"+ e.getMessage());
}

System.out.println(today);

4 个答案:

答案 0 :(得分:3)

您没有输出格式化程序结果的字符串,而是输出实际的日期对象。这将始终是Date.toString()的结果,对于您正在使用的JDK,您看到的格式。不要将格式化的String转回日期对象,只需将其打印出来!

SimpleDateFormat tsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
    String formattedDate = tsdf.format(new Date());
} catch(Exception e) {
    System.out.println("Error occurred"+ e.getMessage());
}

System.out.println(formattedDate);

您无法将“格式”应用于java.util.Date对象以供日后使用。它只是原始的毫秒数,其toString方法将始终打印相同的表示。您必须将其转换为格式化字符串并使用该字符串。

答案 1 :(得分:2)

today = tsdf.parse(tsdf.format(new Date()));
System.out.println(today);

在我看来,Date实例得到格式化。事实并非如此。 Date实例表示可以格式化“到”字符串的日期。它是一个只包含long值的类(意思是“以毫秒为单位的时间”)。

这会产生预期的结果:

Date today = new Date();
String formattedDate = tsdf.format(today);
System.println(formattedDate);     // <- we print the string!!

答案 2 :(得分:0)

如果您希望格式化Date实例,则不必使用parse方法,您必须使用format方法,如下所示:

    Date today = new Date();
    SimpleDateFormat tsdf = new SimpleDateFormat("yyyy-MM-dd");
    try
    {
        System.out.println(tsdf.format(today));
    }
    catch (Exception e)
    {
        System.out.println("Error occurred" + e.getMessage());
    }

parse方法用于将字符串转换为日期,format方法用于将Date实例格式化为指定格式的字符串。

答案 3 :(得分:0)

java.time

您正在使用现在由java.time类取代的旧麻烦的日期时间类。

java.time框架内置于Java 8及更高版本中。这些类取代了旧的麻烦日期时间类,例如java.util.Date.Calendar和&amp; java.text.SimpleDateFormatJoda-Time团队还建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。

大部分java.time功能都被反向移植到Java 6&amp; ThreeTen-Backport中的7,并在ThreeTenABP中进一步适应Android。

LocalDate

对于仅限日期的值,请使用LocalDate类。您的输入值采用标准ISO 8601格式。默认情况下,在java.time类中使用ISO 8601格式来解析和生成表示日期时间值的字符串。因此无需指定格式化模式。

LocalDate localDate = LocalDate.parse( "2012-03-05" );

要生成此类字符串,请调用toString

String output = localDate.toString();

LocalDateTime

对于2012-03-05 12:34:56之类的字符串,我们遇到了问题。未指示与UTC或时区的偏移。因此,它并不代表时间轴上的实际时刻,而是对可能时刻的粗略概念。这个非时刻在java.time中由LocalDateTime类表示。

您的字符串格式是ISO 8601的变体,而规范版本在中间而不是空格中有T。因此,一种选择是用T替换SPACE。

LocalDateTime ldt = LocalDateTime.parse( "2012-03-05 12:34:56".replace( " " , "T" );

或定义模式。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd hh:mm:ss" );
LocalDateTime ldt = LocalDateTime.parse( "2012-03-05 12:34:56" , formatter );

避免使用缺少偏移或时区信息的日期时间格式,如果它们确实代表时间轴上的实际时刻。

ZonedDateTime

要赋予该值意义,要确定时间线上的实际时刻,我们需要指定日期时间所针对的时区。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );

调用toString以扩展ISO 8601标准格式的格式生成字符串,方法是在方括号中附加时区名称。

String output = zdt.toString(); // Yields: 2012-03-05T12:34:56-04:00[America/Montreal]

如果您想省略T,可以使用String::replace方法替换为SPACE。或者使用格式化程序。如果确实想要一个字符串,如问题中所示缺少任何偏移或时区信息(违反我的推荐),请使用上面显示的相同格式化程序。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd hh:mm:ss" );  // Not recommended as it lacks offset/zone info.
String output = zdt.format( formatter );  // Yields: 2012-03-05 12:34:56