如何创build明天午夜和午夜的Java Date对象?

在我的代码中,我需要find今天发生的所有事情。 所以我需要比较今天00:00(凌晨午夜)到12:00(今夜午夜)的date。

我知道 …

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(); 

java.util.Calendar中

 // today Calendar date = new GregorianCalendar(); // reset hour, minutes, seconds and millis date.set(Calendar.HOUR_OF_DAY, 0); date.set(Calendar.MINUTE, 0); date.set(Calendar.SECOND, 0); date.set(Calendar.MILLISECOND, 0); // next day date.add(Calendar.DAY_OF_MONTH, 1); 

JDK 8 – java.time.LocalTime和java.time.LocalDate

 LocalTime midnight = LocalTime.MIDNIGHT; LocalDate today = LocalDate.now(ZoneId.of("Europe/Berlin")); LocalDateTime todayMidnight = LocalDateTime.of(today, midnight); LocalDateTime tomorrowMidnight = todayMidnight.plusDays(1); 

乔达时间

如果您使用的JDK <8,我推荐Joda Time ,因为API非常好:

 DateTime date = new DateTime().toDateMidnight().toDateTime(); DateTime tomorrow = date.plusDays(1); 

由于版本2.3 Joda Time DateMidnight已被弃用 ,所以使用这个:

 DateTime today = new DateTime().withTimeAtStartOfDay(); DateTime tomorrow = today.plusDays(1).withTimeAtStartOfDay(); 

如果您不想要JVM当前的默认时区,则传递时区。

 DateTimeZone timeZone = DateTimeZone.forID("America/Montreal"); DateTime today = new DateTime(timeZone).withTimeAtStartOfDay(); // Pass time zone to constructor. 

请记住, Date不用于表示date (!)。 为了表示date,你需要一个日历。 这个:

 Calendar c = new GregorianCalendar(); 

将创build一个Calendar实例来表示当前时区中的当前date。 现在,您需要的是将date(小时,分钟,秒和毫秒)的每个字段设置为0来截断每个字段。 你现在有一个午夜。

现在到第二天半夜,你需要添加一天:

 c.add(Calendar.DAY_OF_MONTH, 1); 

请注意,由于可能同时发生的夏季时间,增加86400秒或24小时不正确。

更新:但是我最喜欢的方式来处理这个问题是使用Commons Lang的 DateUtils类:

 Date start = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH)) Date end = DateUtils.addDays(start, 1); 

它使用幕后的Calendar

寻找午夜的最简单的方法是:

 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); 

为了完整起见,如果您正在使用Java 8 ,则还可以使用Instant类的truncatedTo方法获取UTC的午夜。

 Instant.now().truncatedTo(ChronoUnit.DAYS); 

正如Javadoc中所写的那样

例如,用MINUTES单位截断将舍入到最接近的分钟,将秒和纳秒设置为零。

希望能帮助到你。

从JodaTime 2.3开始, toDateMidnight()已被弃用。

从2.2升级到2.3

    自从2.2弃用
     ----------------------
     -  DateMidnight [#41]
     这个class在概念上是有缺陷的
     有时在午夜时间不会发生在某些时区
     这是夏令时从00:00到01:00的结果
      DateMidnight本质上是一个时间locking到午夜的时间
     在LocalDate的情况下,这样的概念通常是一个糟糕的概念
     用LocalDatereplaceDateMidnight
     或者用DateTimereplace它,也许使用withTimeAtStartOfDay()方法

这里是一个没有toDateMidnight()方法的示例代码。

 DateTime todayAtMidnight = new DateTime().withTimeAtStartOfDay(); System.out.println(todayAtMidnight.toString("yyyy-MM-dd HH:mm:ss")); 

输出根据您当地的时区可能有所不同

 2013-09-28 00:00:00 

java.time

如果您正在使用Java 8及更高版本,则可以尝试java.time包 ( 教程 ):

 LocalDate tomorrow = LocalDate.now().plusDays(1); Date endDate = Date.from(tomorrow.atStartOfDay(ZoneId.systemDefault()).toInstant()); 

这似乎是一个select:

 DateFormat justDay = new SimpleDateFormat("yyyyMMdd"); Date thisMorningMidnight = justDay.parse(justDay.format(new Date())); 

给它添加一天

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

要么

 Calendar c = Calendar.getInstance(); c.setTime(thisMorningMidnight); c.add(Calendar.DATE, 1); Date tomorrowFromCalendar = c.getTime(); 

我有一个预感后者是首选的情况下,像夏令时导致增加24小时不够的奇怪(见https://stackoverflow.com/a/4336131/32453及其他答案)。;

这些方法将帮助你 –

 public static Date getStartOfDay(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(); } 

 public static Date getEndOfDay(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.HOUR_OF_DAY, 23); calendar.set(Calendar.MINUTE, 59); calendar.set(Calendar.SECOND, 59); calendar.set(Calendar.MILLISECOND, 999); return calendar.getTime(); } 

其他答案是正确的,特别是由arganzheng的java.time答案 。 正如一些人提到的,你应该避免使用旧的java.util.Date/.Calendar类,因为它们devise不好,令人困惑和麻烦。 它们已经被java.time类所取代。

让我补充一下关于处理午夜跨越时间的策略

半开

在date时间工作中,时间跨度通常使用“半开放”方法来定义。 在这种方法中,开始是包容性的,而结束是排他性的 。 这解决了问题,如果一直使用推理date时间处理更容易。

解决的一个问题是定义一天的结束。 是23:59:59.999 ( 毫秒 )的最后一刻吗? 也许,在java.util.Date类(从最早的Java;麻烦 – 避免这个类!)和非常成功的Joda时间库。 但在其他软件,如Postgres等数据库中,最后一刻将是23:59:59.999999 ( 微秒 )。 但是在诸如java.time框架(内置于Java 8及更高版本,Joda-Time的后续版本)以及某些数据库如H2数据库的其他软件中 ,最后时刻可能是23:59.59.999999999 ( 纳秒 )。 而不是分头发,只考虑第一时间,而不是最后一刻。

在半开放中,一天从一天的第一时刻开始,一直到第二天的第一时刻。 所以不要这样想:

…从今天上午00:00(凌晨午夜)到中午12:00(今晚的午夜)。

…这样想…

从今天跑到但不包括明天的第一刻起:
(> = 00:00:00.0 ,明天< 00:00:00.0

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

一天的开始

而且,一天中的第一个时刻并不总是时间为00:00:00.0 。 夏令时(DST)在某些时区以及其他可能的exception情况下,可能意味着不同的时间开始一天。

所以让java.time类通过调用LocalDate::atStartOfDay( ZoneId )来完成确定一天的开始的工作。 所以我们必须绕过LocalDate并返回到ZonedDateTime就像你在这个例子中看到的那样。

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

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

时区对date时间工作至关重要。 这个问题和其他答案可能有缺陷,因为不自觉地处理时区。

兑换

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

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

时间的跨度

顺便说一下,如果你正在做很多工作,请看看:

  • Duration
  • Period
  • Interval
    Interval类在ThreeTen-Extra项目中find,它是java.time框架的扩展。 这个项目是未来可能增加java.time的试验场。
    Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );

我做了这个不同于这里的其他人。 我是Java新手,所以也许我的解决scheme很差。

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

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

我对上面的说法感到困惑,你可以通过调用明天来计算:

 c.add(Calendar.DAY_OF_MONTH, 1); 

如果你在月份的当天加上1,而今天是31天,那么你是不是获得了本月的第32天?

为什么时间/date不是基于Java的UTC? 我认为只有在使用I / O时才需要时区,但内部应始终以UTC使用。 但是,这些类似乎包括时区信息,这些信息似乎不仅浪费,而且容易出现编码错误。

JodaTime最简单的方法

DateMidnight date = DateMidnight.now();

因为有一天是24 * 60 * 60 * 1000毫秒,这一天的午夜可以计算为…

 long now = System.currentTimeMillis(); long delta = now % 24 * 60 * 60 * 1000; long midnight = now - delta; Date midnightDate = new Date(midnight);` 

我知道这是很老的post。 我想在这里分享我的知识!

对于今天中午的确切时区,你可以使用以下的date

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

在哪里(1000*60 * 330)正在被扣除,即实际上与时区有关,例如印度时区,即Kolkata与实际时间相差+5:30小时。 所以把它转换成毫秒

所以根据你的改变最后减号。 我创build一个产品,即只在印度所以只是使用特定的时间戳。

 Date todayMidnightUTC = java.sql.Date.valueOf(LocalDate.now()); Date tomorrowMidnightUTC = java.sql.Date.valueOf(LocalDate.now().plusDays(1)); Date anyMidnightLocal = java.sql.Date.valueOf(LocalDate.from(dateTime.toInstant().atZone(ZoneId.systemDefault()))); 

但要小心, java.sql.Date.toInstant()总是抛出UnsupportedOperationException

通过LocalDate到java.util.Date,反之亦然最简单的转换?