11

所以我使用dateString1.compareTo(dateString2)which 根据每个字符的 Unicode 值与字符串进行字典比较,并返回一个 int。这是一个代码示例。

String dateString1 = "05-12-2012";
String dateString2 = "05-13-2012";
if (dateString1.compareTo(dateString2) <=0){
   System.out.println("dateString1 is an earlier date than dateString2");
}

这是在 Java 中比较日期的错误方法吗?

在我的测试中,我没有遇到意外结果的情况。如果我不需要的话,我真的不想从字符串中创建一个 Date 对象,因为我在一个长时间运行的循环中执行此操作。

Ninja Edit 从下面的答案中收集到,如果日期是格式的,将日期作为字符串进行比较没有任何问题,yyyyMMdd但如果它是任何其他格式,显然会导致错误。

我实际上yyyyMMdd在我的实际代码中将日期字符串作为格式。(我在上面给出的示例中输入了错误的格式。)所以现在,我将保持代码不变,并添加几行注释来证明我的决定。

但是我现在看到,像这样比较字符串是非常有限的,如果 dba 决定在以后更改日期格式,我会遇到错误,而我认为这不会发生。

4

6 回答 6

18

在 Java 中使用字符串处理日期并不总是最好的选择。例如,当是闰年时,二月会多出一天。因为字符串可能看起来是正确的,所以执行转换更合适。Java 验证日期是否正确。

您可以使用SimpleDateFormat类将字符串转换为日期。

public static void main(String[] args) throws ParseException {
    String dateString1 = "05-12-2012";
    String dateString2 = "05-13-2012";

    SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");

    Date date1 = format.parse(dateString1);
    Date date2 = format.parse(dateString2);

    if (date1.compareTo(date2) <= 0) {
        System.out.println("dateString1 is an earlier date than dateString2");
    }
}

要找出允许检查自定义格式的参数(Java™ 教程 > 国际化 > 格式)

于 2012-05-15T22:34:34.553 回答
8

我建议您做正确的事情(如此处所述)并转换为适当的Date对象进行比较。如果以及何时实际影响您的应用程序(它可能不会),请担心性能影响。

于 2012-05-15T22:23:44.130 回答
4

这很糟糕,因为现在你无法处理一年的变化。

如果你想这样做,你可能想要格式化日期,YYYY-MM-DD这样新的一年就不会毁了它。

于 2012-05-15T22:20:47.317 回答
3

使用字母排序规则来处理日期排序是不好的,主要是因为您遇到了根据字母和数字系统对事物进行不同排序的问题

对于字母表

01-02-2011 comes before
01-1-2011 (because 0 in the date field is before 1 in the other date field)

对于数制

01, 02, 2011 comes after
01, 1, 2011  because all fields are being compared like numbers

日期对象扩展了数字比较以了解哪些字段在比较中优先,因此您不会得到较早的月份将日期“放在”另一个实际发生在后一个月但较早年份的日期之前。

如果您对日期格式有严格的控制,您可以对齐日期,使其也遵循字母规则;但是,如果您不小心注入了格式错误的日期,这样做可能会使您的整个程序以奇怪的方式失败。

典型的做法是(不推荐,请使用非字符串日期比较)

YYYYMMDD
(year)(month)(day) all zero-padded.

最后一种技术主要是因为您最终会在野外看到它,并且应该认清它的本质:尝试在没有适当日期库的情况下处理日期(又名聪明的 hack)。

于 2012-05-17T15:14:09.420 回答
2

正如所讨论的,通常使用日期时间对象而不是字符串更好。

java.time

其他答案使用旧的过时的日期时间类,这些类已被证明设计不良、令人困惑且麻烦。它们缺少一个类来真正表示没有时间和时区的纯日期值。

而是使用Java 8 及更高版本中内置的java.time框架。请参阅Oracle 教程。许多 java.time 功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7,并在ThreeTenABP进一步适应 Android 。

String input = "05-12-2012";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM-dd-yyyy" );
LocalDate ld = LocalDate.parse( input , formatter );

LocalDate工具compareTo。_ 此外,您可以调用方法 equals、isBefore、isAfter。

Boolean isEarlier = ld.isBefore( someOtherLocalDate );
于 2016-07-12T16:59:48.910 回答
1

如果您只对每个日期进行一次读取,那么 YYYYMMDD(而不是您所做的 MMDDYYYY)可能是最佳解决方案。但是,当您打算多次处理每个日期时(例如,您正在对它们进行排序),那么肯定最好将它们更改为可以比字符串更快地进行比较的对象(例如日期)

于 2012-05-15T23:44:58.990 回答