如何创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使用。 但是,这些类似乎包括时区信息,这些信息似乎不仅浪费,而且容易出现编码错误。
Apache Commons Lang
DateUtils.isSameDay(date1, date2)
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,反之亦然最简单的转换?