我想有一个compareTo方法来忽略java.util.Date的时间部分。我想有很多方法可以解决这个问题。最简单的方法是什么?


当前回答

`

SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")

   Date date1=sdf.parse("03/25/2015");



  Date currentDate= sdf.parse(sdf.format(new Date()));

   return date1.compareTo(currentDate);

`

其他回答

我更倾向于直接使用Joda库而不是java.util.Date,因为Joda区分了日期和时间(参见YearMonthDay和DateTime类)。

然而,如果你确实希望使用java.util.Date,我建议写一个实用方法;如。

public static Date setTimeToMidnight(Date date) {
    Calendar calendar = Calendar.getInstance();

    calendar.setTime( date );
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    return calendar.getTime();
}

如果严格使用Date (java.util.Date),或者不使用任何外部库。用这个:

public Boolean compareDateWithoutTime(Date d1, Date d2) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    return sdf.format(d1).equals(sdf.format(d2));
}

博士tl;

myJavaUtilDate1.toInstant()
               .atZone( ZoneId.of( "America/Montreal" ) )
               .toLocalDate()
               .isEqual (
                   myJavaUtilDate2.toInstant()
                                  .atZone( ZoneId.of( "America/Montreal" ) )
                                  .toLocalDate()
               )

避免遗留的日期-时间类

避免麻烦的旧的遗留日期时间类,如Date & Calendar,现在已被java所取代。时间类。

使用java.time

date表示时间轴上的一个UTC时间点。在java中是等价的。时间就是瞬间。您可以使用添加到遗留类中的新方法进行转换。

Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();

您希望根据日期进行比较。时区是决定日期的关键。对于任何给定的时刻,全球各地的日期都因地区而异。例如,法国巴黎午夜过后几分钟就是新的一天,但在Montréal Québec上仍然是“昨天”。

请指定合适的时区名称,如“America/Montreal”、“Africa/Casablanca”或“Pacific/Auckland”。不要使用3-4个字母的缩写,如EST或IST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Montreal" );

将ZoneId应用到Instant以获得zoneeddatetime。

ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );

LocalDate类表示一个只包含日期的值,不包含日期和时区。我们可以从ZonedDateTime中提取LocalDate,有效地消除了日期部分。

LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();

现在使用isEqual、isBefore和isAfter等方法进行比较。

Boolean sameDate = localDate1.isEqual( localDate2 );

请在IdeOne.com上查看实时运行的代码。

即时1: 2017-03-25T04:13:10.971Z |即时2: 2017-03-24T22:13:10.972Z ZDT1: 2017-03-25T00:13:10.971-04:00[美国/蒙特利尔] |ZDT2:2017-03-24T18:13:10.972-04:00[美国/蒙特利尔] 本地日期1: 2017-03-25 |本地日期2: 2017-03-24 同一日期:假


关于java.time

java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。

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

要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。

从哪里获取java。时间类?

Java SE 8和SE 9及更高版本 内置的。 带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小特性并进行了修复。 Java SE 6和SE 7 大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7。 安卓 ThreeTenABP项目将ThreeTen-Backport(上文提到过)专门用于Android。 参见如何使用ThreeTenABP....

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。

首先,请注意该操作取决于时区。所以你可以选择使用国际标准时间(UTC)、计算机时区、你自己喜欢的时区或其他地方。如果你还不相信这很重要,请参阅下面我的例子。

由于您的问题不是很清楚这一点,我假设您有一个类,它具有一个实例字段,表示时间点并实现Comparable,并且您希望对象的自然顺序是根据该字段的日期而不是时间。例如:

public class ArnesClass implements Comparable<ArnesClass> {

    private static final ZoneId arnesTimeZone = ZoneId.systemDefault();

    private Instant when;

    @Override
    public int compareTo(ArnesClass o) {
        // question is what to put here
    }

}

Java 8 Java。时间类

我已经自由地将实例字段的类型从Date更改为Instant,这是Java 8中对应的类。我保证会继续下面对Date的处理。我还添加了一个时区常数。您可以将其设置为ZoneOffset。UTC或ZoneId.of("Europe/Stockholm")或您认为合适的名称(将其设置为ZoneOffset是有效的,因为ZoneOffset是ZoneId的子类)。

我选择使用Java 8类来展示解决方案。你要的是最简单的方法,对吧?:-)这是你要求的compareTo方法:

public int compareTo(ArnesClass o) {
    LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
    LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
    return dateWithoutTime.compareTo(otherDateWithoutTime);
}

如果您永远不需要when的时间部分,那么声明when为LocalDate并跳过所有转换当然更容易。那我们也不用担心时区的问题了。

现在假设由于某种原因,您不能将您的when字段声明为Instant,或者希望将其保留为老式的Date。如果你仍然可以使用Java 8,只需将其转换为Instant,然后像以前那样做:

    LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();

与o.when类似。

没有Java 8?

如果你不能使用java 8,有两个选项:

使用一个旧类(Calendar或SimpleDateFormat)来解决这个问题。 使用Java 8日期和时间类的后端口到Java 6和7,然后执行上述操作。我在底部附上了一个链接。不要使用JodaTime。JodaTime可能是一个很好的建议,当答案推荐它编写;但是JodaTime现在处于维护模式,所以ThreeTen后端口是一个更好的、更适合未来的选择。

传统的方式

Adamski的回答向您展示了如何使用Calendar类从Date中剥离时间部分。我建议您使用getInstance(TimeZone)来获取所需时区的Calendar实例。作为替代,你可以使用Jorn回答的后半部分的想法。

使用SimpleDateFormat实际上是使用Calendar的一种间接方式,因为SimpleDateFormat包含一个Calendar对象。然而,你可能会发现它比直接使用Calendar麻烦得多:

private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
    formatter.setTimeZone(arnesTimeZone);
}

private Date when;

@Override
public int compareTo(ArnesClass o) {
    return formatter.format(when).compareTo(formatter.format(o.when));
}

这是受到了罗伯的回答的启发。

时区依赖性

Why do we have to pick a specific time zone? Say that we want to compare two times that in UTC are March 24 0:00 (midnight) and 12:00 (noon). If you do that in CET (say, Europe/Paris), they are 1 am and 1 pm on March 24, that is, the same date. In New York (Eastern Daylight Time), they are 20:00 on March 23 and 8:00 on March 24, that is, not the same date. So it makes a difference which time zone you pick. If you just rely on the computer’s default, you may be in for surprises when someone tries to run your code on a computer in another place in this globalized world.

Link

链接到ThreeTen Backport, Java 8日期和时间类到Java 6和7的后端口:http://www.threeten.org/threetenbp/。

只需结合YEAR属性检查DAY_OF_YEAR

boolean isSameDay = 
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)

编辑:

现在我们可以使用Kotlin扩展函数的强大功能

fun Calendar.isSameDay(second: Calendar): Boolean {

    return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}

fun Calendar.compareDatesOnly(other: Calendar): Int {

    return when {
        isSameDay(other) -> 0
        before(other) -> -1
        else -> 1
    }
}