在Java中重置时间戳的时间部分

在Java中,给定一个时间戳,如何将时间部分单独重置为00:00:00,以便时间戳表示该特定日子的午夜?

在T-SQL中,这个查询将做到这一点,但我不知道如何在Java中做到这一点。

SELECT CAST( FLOOR( CAST(GETDATE() AS FLOAT ) ) AS DATETIME) AS 'DateTimeAtMidnight';

你可以去date – >日历 – >设置 – >date:

 Date date = new Date(); // timestamp now Calendar cal = Calendar.getInstance(); // get calendar instance cal.setTime(date); // set cal to date cal.set(Calendar.HOUR_OF_DAY, 0); // set hour to midnight cal.set(Calendar.MINUTE, 0); // set minute in hour cal.set(Calendar.SECOND, 0); // set second in minute cal.set(Calendar.MILLISECOND, 0); // set millis in second Date zeroedDate = cal.getTime(); // actually computes the new Date 

我爱Javadate。

请注意,如果您使用的是实际的java.sql.Timestamps,则它们具有额外的纳米字段。 日历当然,对nanos一无所知,所以在最后创buildzeroedDate时,会盲目地忽略它,然后有效地删除它,然后可以使用它创build一个新的Timetamp对象。

我还应该注意到,Calendar不是线程安全的,所以不要以为可以从多个线程调用一个静态的单个实例来避免创build新的Calendar实例。

如果您使用的是commons lang,则可以调用DateUtils.truncate 。 这里是javadoc文档 。

亚历山大·米勒(Alexander Miller)说要做同样的事情。

假设你的“timestamp”是一个java.util.Date,它表示为从纪元开始(1970年1月1日)开始的毫秒数,你可以执行下面的algorithm:

 public static Date stripTimePortion(Date timestamp) { long msInDay = 1000 * 60 * 60 * 24; // Number of milliseconds in a day long msPortion = timestamp.getTime() % msInDay; return new Date(timestamp.getTime() - msPortion); } 

我喜欢这个解决scheme:

 GregorianCalendar now = new GregorianCalendar(); GregorianCalendar calendar = new GregorianCalendar( now.get(GregorianCalendar.YEAR), now.get(GregorianCalendar.MONTH), now.get(GregorianCalendar.DAY_OF_MONTH)); 

做这个

 import org.apache.commons.lang.time.DateUtils; Date myDate = new Date(); System.out.println(myDate); System.out.println(DateUtils.truncate(myDate, Calendar.DATE)); 

和输出是

Wed Mar 19 14:16:47 PDT 2014
星期三3月19日00:00:00 PDT 2014

由于我不做太多的date时间操作,这可能不是最好的办法。 我会产生一个日历,并使用date作为源。 然后将小时,分钟和秒设置为0并转换回date。 虽然,看到更好的方法会很高兴。

使用Calendar.set()可以certificate是“通过本书”的解决scheme,但你也可以使用java.sql.Date:

 java.util.Date originalDate = new java.util.Date(); java.sql.Date wantedDate = new java.sql.Date(originalDate.getTime()); 

这将做你想要的,因为:

为了符合SQL DATE的定义,由java.sql.Date实例包装的毫秒值必须通过将与实例关联的特定时区中的小时,分​​钟,秒和毫秒设置为零来“标准化” 。

由于java.sql.Date扩展了java.util.Date,因此您可以自由使用它。 请注意,wantedDate.getTime()将检索原始时间戳 – 这就是为什么您不想从java.sql.Date创build另一个java.util.Date的原因!

在下面find一个采用Joda Time并支持时区的解决scheme。 因此,您将获取当前date和时间(到currentDatecurrentTime )或您在JVM当前configuration的时区中通知(到达informedDatedate和通知时间)的某个date和时间。

下面的代码还通知是否将来的通知date/时间(variablesschedulable )。

请注意,Joda Time不支持闰秒 。 所以,你可以离真正的价值26或27秒。 这大概只能在未来50年才能解决,累计误差将近1分钟,人们就会开始关心它。

另见: https : //en.wikipedia.org/wiki/Leap_second

 /** * This class splits the current date/time (now!) and an informed date/time into their components: * <lu> * <li>schedulable: if the informed date/time is in the present (now!) or in future.</li> * <li>informedDate: the date (only) part of the informed date/time</li> * <li>informedTime: the time (only) part of the informed date/time</li> * <li>currentDate: the date (only) part of the current date/time (now!)</li> * <li>currentTime: the time (only) part of the current date/time (now!)</li> * </lu> */ public class ScheduleDateTime { public final boolean schedulable; public final long millis; public final java.util.Date informedDate; public final java.util.Date informedTime; public final java.util.Date currentDate; public final java.util.Date currentTime; public ScheduleDateTime(long millis) { final long now = System.currentTimeMillis(); this.schedulable = (millis > -1L) && (millis >= now); final TimeZoneUtils tz = new TimeZoneUtils(); final java.util.Date dmillis = new java.util.Date( (millis > -1L) ? millis : now ); final java.time.ZonedDateTime zdtmillis = java.time.ZonedDateTime.ofInstant(dmillis.toInstant(), java.time.ZoneId.systemDefault()); final java.util.Date zdmillis = java.util.Date.from(tz.tzdate(zdtmillis)); final java.util.Date ztmillis = new java.util.Date(tz.tztime(zdtmillis)); final java.util.Date dnow = new java.util.Date(now); final java.time.ZonedDateTime zdtnow = java.time.ZonedDateTime.ofInstant(dnow.toInstant(), java.time.ZoneId.systemDefault()); final java.util.Date zdnow = java.util.Date.from(tz.tzdate(zdtnow)); final java.util.Date ztnow = new java.util.Date(tz.tztime(zdtnow)); this.millis = millis; this.informedDate = zdmillis; this.informedTime = ztmillis; this.currentDate = zdnow; this.currentTime = ztnow; } } public class TimeZoneUtils { public java.time.Instant tzdate() { final java.time.ZonedDateTime zdtime = java.time.ZonedDateTime.now(); return tzdate(zdtime); } public java.time.Instant tzdate(java.time.ZonedDateTime zdtime) { final java.time.ZonedDateTime zddate = zdtime.truncatedTo(java.time.temporal.ChronoUnit.DAYS); final java.time.Instant instant = zddate.toInstant(); return instant; } public long tztime() { final java.time.ZonedDateTime zdtime = java.time.ZonedDateTime.now(); return tztime(zdtime); } public long tztime(java.time.ZonedDateTime zdtime) { final java.time.ZonedDateTime zddate = zdtime.truncatedTo(java.time.temporal.ChronoUnit.DAYS); final long millis = zddate.until(zdtime, java.time.temporal.ChronoUnit.MILLIS); return millis; } } 

这里有一个简单的函数,主要的例子是:

 import java.util.Calendar; import java.util.Date; public class Util { /** * Returns an imprecise date/timestamp. * @param date * @return the timestamp with zeroized seconds/milliseconds */ public static Date getImpreciseDate(Date date) { Calendar cal = Calendar.getInstance(); // get calendar instance cal.setTime(date);// set cal to date cal.set(Calendar.SECOND, 0); // zeroize seconds cal.set(Calendar.MILLISECOND, 0); // zeroize milliseconds return cal.getTime(); } public static void main(String[] args){ Date now = new Date(); now.setTime(System.currentTimeMillis()); // set time to now System.out.println("Precise date: " + Util.getImpreciseDate(now)); System.out.println("Imprecise date: " + Util.getImpreciseDate(now)); } }