SimpleDateFormat 解析错误的日期

SimpleDateFormat parsing wrong date

我在这里尝试比较 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

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

你的格式是日然后月然后年,但大概你的字符串是月然后日然后年,看看 tDate,中间有 25,所以不能是月

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

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

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

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

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

tl;博士

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".
    )
)

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

你说:

make 3 dates of the same format so that I can compare them

使用具有比较方法的对象,而不是比较字符串的文本。

我们在 Java 中内置了一个 class 日期:LocalDate

java.time

您正在使用 Date,这是与 Java 的最早版本捆绑在一起的糟糕日期时间 classes 之一。这些 classes 现在已经过时,多年前被 JSR 310 取代,JSR 310 定义了 java.time classes.

I have passed a date

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

Instant instant = myJavaUtilDate.toInstant() ;

java.util.Datejava.time.Instant 都代表 UTC 中的一个时刻。这就是您想要以 UTC 格式从本初子午线偏移零小时-分钟-秒的日期的方式吗?请记住,对于任何给定时刻,日期在全球范围内因地区而异。片刻可能在日本东京 "tomorrow" 而在美国俄亥俄州托莱多仍然 "yesterday"。

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.

and two string to a function

定义格式模式以匹配您的输入。

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

Can anyone tell where did I go wrong?

您的主要问题是您的格式设置模式未定义为符合您的意图。这在 and the 中被正确识别。

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

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


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

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

从哪里获得java.time classes?