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

在T-SQL中,此查询将实现相同的目标,但我不知道如何在Java中执行此操作。

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

有帮助吗?

解决方案

您可以进入日期 - >日历 - >设置 - >日期:

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

我喜欢Java约会。

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

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

其他提示

如果您使用的是公共语言,则可以调用 DateUtils.truncate 。这是 javadoc文档

@Alex Miller说过这样做。

假设您的“时间戳”是java.util.Date,表示为自纪元开始(1970年1月1日)以来的毫秒数,您可以执行以下算术:

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

我更喜欢这个解决方案:

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
2014年3月19日星期三00:00:00 PDT 2014

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

使用Calendar.set()可能会“通过书籍”。解决方案,但您也可以使用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,因此您可以自由地使用它。请注意,wantDate.getTime()将检索原始时间戳 - 这就是为什么你不想从java.sql.Date创建另一个java.util.Date!

在下面找到一个采用Joda Time并支持时区的解决方案。 因此,您将获得当前日期和时间(进入 currentDate currentTime )或您通知的一些日期和时间(进入 informedDate informTime )在JVM中当前配置的时区。

下面的代码还会告知将来的通知日期/时间(变量 schedulable )。

请注意,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));
}
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top