在我的代码中,我需要找到今天发生的所有事情。因此,我需要将今天凌晨00:00(今天凌晨午夜)到中午12:00(今晚午夜)的日期进行比较。

我知道……

Date today = new Date(); 

... 我现在很生气。和…

Date beginning = new Date(0);

…1970年1月1日是零。但是有什么简单的方法可以让你今天和明天的时间都为零呢?


更新

我做到了,但肯定有更简单的方法吧?

Calendar calStart = new GregorianCalendar();
calStart.setTime(new Date());
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
Date midnightYesterday = calStart.getTime();
            
Calendar calEnd = new GregorianCalendar();
calEnd.setTime(new Date());
calEnd.set(Calendar.DAY_OF_YEAR, calEnd.get(Calendar.DAY_OF_YEAR)+1);
calEnd.set(Calendar.HOUR_OF_DAY, 0);
calEnd.set(Calendar.MINUTE, 0);
calEnd.set(Calendar.SECOND, 0);
calEnd.set(Calendar.MILLISECOND, 0);
Date midnightTonight = calEnd.getTime();

当前回答

我知道这是一个很老的帖子。我想在这里分享我的知识!

对于日期今天午夜与准确的时区,您可以使用以下

public static Date getCurrentDateWithMidnightTS(){

    return new Date(System.currentTimeMillis() - (System.currentTimeMillis()%(1000*60*60*24)) - (1000*60 * 330));
}

其中(1000*60 * 330)被减去,即实际上与时区有关,例如印度时区,即加尔各答与实际时差+5:30小时。减去换算成毫秒的时间。

所以根据你的需要改变最后一个减数。我正在创建一个产品,即只基于印度,所以只是使用特定的时间戳。

其他回答

老式的方式…

private static Date getDateWithMidnight(){
    long dateInMillis = new Date().getTime();
    return new Date(dateInMillis - dateInMillis%(1000*60*60*24) - TimeZone.getDefault().getOffset(dateInMillis));
}

找到午夜最简单的方法:

Long time = new Date().getTime();
Date date = new Date(time - time % (24 * 60 * 60 * 1000));

第二天:

Date date = new Date(date.getTime() + 24 * 60 * 60 * 1000);

使用apache commons..

//For midnight today 
Date today = new Date(); 
DateUtils.truncate(today, Calendar.DATE);

//For midnight tomorrow   
Date tomorrow = DateUtils.addDays(today, 1); 
DateUtils.truncate(tomorrow, Calendar.DATE);

其他答案都是正确的,尤其是java。时间回答由干政。正如一些人提到的,应该避免使用旧的java.util.Date/。日历类,因为它们设计得很差,令人困惑,而且很麻烦。他们已经被爪哇取代了。时间类。

让我补充一些关于处理午夜和时间跨度的策略。

半开的

在日期-时间工作中,时间跨度通常使用“半开放”方法来定义。在这种方法中,开始是包容的,而结束是排外的。这可以解决问题,如果始终使用,可以更容易地推理日期时间处理。

One problem solved is defining the end of the day. Is the last moment of the day 23:59:59.999 (milliseconds)? Perhaps, in the java.util.Date class (from earliest Java; troublesome – avoid this class!) and in the highly successful Joda-Time library. But in other software, such as database like Postgres, the last moment will be 23:59:59.999999 (microseconds). But in other software such as the java.time framework (built into Java 8 and later, successor to Joda-Time) and in some database such the H2 Database, the last moment might be 23:59.59.999999999 (nanoseconds). Rather than splitting hairs, think in terms of first moment only, not last moment.

在半开放中,一天从一天的第一个时刻算起,但不包括第二天的第一个时刻。所以与其这样想:

从今天凌晨0点(今天凌晨12点)到下午12点(今晚12点)。

这样想…

从今天的第一个时刻到但不包括明天的第一个时刻:(>=今天的00:00:00.0 AND <明天的00:00:00.0)

在数据库工作中,这种方法意味着不在SQL中使用BETWEEN操作符。

一天的开始

此外,一天的第一个时刻并不总是一天中的00:00:00.0。某些时区的日光节约时间(DST),以及可能存在的其他异常情况,可能意味着一天开始的时间不同。

所以让java。time类通过调用LocalDate::atStartOfDay(ZoneId)来确定一天的开始。因此,我们必须绕过LocalDate,返回到本例代码中所示的zoneeddatetime。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime todayStart = now.toLocalDate().atStartOfDay( zoneId );
ZonedDateTime tomorrowStart = todayStart.plusDays( 1 );

注意可选的ZoneId的传递。如果省略,则隐式应用JVM的当前默认时区。最好是明确一点。

时区对约会时间工作至关重要。这个问题和其他一些答案有潜在的缺陷,因为它们没有有意识地处理时区。

转换

如果必须使用java.util.Date或. calendar,请寻找添加到这些旧类中的新转换方法。

java.util.Date utilDate = java.util.Date.from( todayStart.toInstant() );
java.util.GregorianCalendar gregCal = java.util.GregorianCalendar.from( todayStart );

时间跨度

顺便说一下,如果你在一段时间内做了很多工作,可以看看:

持续时间 期 Interval类可以在ThreeTen-Extra项目中找到,它是java的扩展。时间框架。这个项目是未来可能添加到java.time.Interval todayMontreal = Interval的试验场。of(todayStart.toInstant(), tomorrowStart.toInstant());


关于java.time

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

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

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

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

从哪里获取java。时间类?

Java SE 8、Java SE 9、Java SE 10、Java SE 11及更高版本——带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小特性并进行了修复。 Java SE 6和Java SE 7 大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7。 安卓 后续版本的Android捆绑实现的java。时间类。 对于早期的Android (<26), ThreeTenABP项目适应ThreeTen-Backport(如上所述)。参见如何使用ThreeTenABP....

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

我的做法和这里的其他人都不一样。我刚接触Java,所以我的解决方案可能很差。

Date now = new Date();
Date midnightToday = new Date(now.getYear(), now.getMonth(), now.getDate());

我不确定这是否有效,但无论如何,我很感激任何关于这个解决方案的反馈。

我对上面的陈述感到困惑,你可以通过调用:

c.add(Calendar.DAY_OF_MONTH, 1);

如果你在这个月的第几天加上1是31天,你不是得到了这个月的第32天吗?

为什么Java中的时间/日期不是全部基于UTC ?我认为时区应该只在与I /o一起使用时才需要,但在内部应该总是在UTC中使用。然而,这些类似乎包含了Timezone信息,这不仅浪费时间,而且容易产生编码错误。