SimpleDateFormat解析错误的日期

时间:2020-03-25 21:50:31

标签: java date simpledateformat

在这里,我试图比较3个日期,为此,我向一个函数传递了一个日期和两个字符串。我正在使用简单的日期格式来制作3个相同格式的日期,以便可以进行比较。但是对于两个字符串值,我在解析它时得到了错误的日期。谁能帮忙吗?

Private boolean compareDate(Date cdate, String fdate, String date) {
    //cdate = 2020-03-25 09:05:47
    //fdate = 03/10/2020
    //tdate = 03/25/2020

    SimpleDateFormat sd= new SimpleDateFormat("dd/MM/yyyy");
    String s=sd.format(cdate);
    Date d1=sd.parse(s);
    Date d2=sd.parse(fdate);
    Date d3=sd.parse(tdate);
}

解析后得到的值是:

D1 = wed Mar 25 00:00:00 IST 2020
D2 = sat Oct 03 00:00:00 IST 2020 //wrong date fdate was 03/10/2020
D3 = Mon Jan 03 00:00:00 IST2020 //wrong date  tdate was 03/25/2020

谁能告诉我我哪里出了错?由于这个问题,我无法正确比较它们。

3 个答案:

答案 0 :(得分:3)

tl; dr

myJavaUtilDate 
.toInstant()
.atZone
(
    ZoneId.of( "Asia/Kolkata" ) 
)
.toLocalDate()
.isEqual
(
    LocalDate
    .parse
    (
        "03/10/2020" ,                              // Do you mean March 10th, or October 3rd? 
        DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) // Or "MM/dd/uuuu".
    )
)

智能对象,而不是哑字符串

您说:

制作3个相同格式的日期,以便我进行比较

将对象与比较方法一起使用,而不是比较字符串的文本。

我们有一个内置于Java中的日期类:LocalDate

java.time

您正在使用Date,它是与最早的Java版本捆绑在一起的可怕的日期时间类之一。这些类现在已经过时了,几年前通过定义 java.time 类的JSR 310取代了。

我已经过了日期

遇到java.util.Date对象时,请立即转换为现代替换对象java.time.Instant。使用添加到旧类中的新转换方法toInstant

Instant instant = myJavaUtilDate.toInstant() ;

java.util.Datejava.time.Instant都表示UTC时刻。这就是您要如何以UTC来感知日期,并且与本初子午线的偏移为零小时-分钟-秒吗?请记住,在任何给定时刻,日期都会在全球范围内变化。在日本东京可能是“明天”,而在美国俄亥俄州托莱多仍然是“昨天”。

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

提取日期。

LocalDate ld = odt.toLocalDate() ;  // Extract the date only, omitting the time-of-day and the offset-from-UTC.

还是您想在特定区域中看到该日期?

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
LocalDate ld = zdt.toLocalDate() ;  // Extract the date only, omitting the time-of-day and the zone.

和一个函数的两个字符串

定义一种格式设置以匹配您的输入。

String input = "03/10/2020" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;  // Throws `DateTimeParseException` if input is faulty.

现在使用方法isEqualisAfterisBefore进行比较。

boolean datesMatch = ld1.isEqual( ld2 ) && ld2.isEqual( ld3 ) ;

java.util.Date::toString撒谎

您问:

D2 = sat Oct 03 00:00:00 IST 2020 //wrong date fdate was 03/10/2020

谁能告诉我我出了什么问题?

您的主要问题是您的格式化模式未定义为符合您的意图。在Answer by ChrisAnswer by Arvind Kumar Avinash中可以正确识别。

此外,您还有另一个问题。 java.util.Date的众多问题之一是它的toString方法在生成用于表示对象内容的文本时即时应用了JVM当前的默认时区。这产生了将该区域存储在对象中的错觉。调整到时区后,如果感知Date对象的UTC值,则日期可能与UTC中显示的日期不同。上面已经讨论过了。

➥永远不要使用java.util.Date


关于 java.time

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

要了解更多信息,请参阅Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规范为JSR 310

Joda-Time项目(现在位于maintenance mode中)建议迁移到java.time类。

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

在哪里获取java.time类?

答案 1 :(得分:1)

您的格式是天又月然后年,但是大概您的字符串是月然后天,再看tDate,中间有25个,所以不能是一个月。

答案 2 :(得分:1)

问题是由于格式和日期字符串不匹配。您的格式化程序如下:

SimpleDateFormat sd= new SimpleDateFormat("dd/MM/yyyy");

而您的日期字符串例如03/10/202003/25/2020的格式为MM/dd/yyyy

更改其中两个以匹配另一个。

我还建议您使用Modern date/time API而不是损坏的DateSimpleDateFormat类。

相关问题