繁体   English   中英

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

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

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

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

你说:

制作 3 个相同格式的日期,以便我可以比较它们

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

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

时间

您正在使用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

谁能告诉我哪里出错了?

您的主要问题是您的格式模式未定义为符合您的意图。 这在Chris答案和 Arvind Kumar Avinash答案中得到了正确识别。

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

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


关于java.time

java.time框架内置于 Java 8 及更高版本中。 这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar ,和SimpleDateFormat

要了解更多信息,请参阅Oracle 教程 并在 Stack Overflow 上搜索许多示例和解释。 规范是JSR 310

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

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

从哪里获得 java.time 类?

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

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

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

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

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

我还建议您使用现代日期/时间 API,而不是损坏的DateSimpleDateFormat类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM