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

时间:2021-07-26 21:43:27

In Java, given a timestamp, how to reset the time part alone to 00:00:00 so that the timestamp represents the midnight of that particular day ?

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

In T-SQL, this query will do to achieve the same, but I don't know how to do this in Java.

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

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

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

9 个解决方案

#1


75  

You can go Date->Calendar->set->Date:

你可以去Date-> Calendar-> set-> 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

I love Java dates.

我喜欢Java约会。

Note that if you're using actual java.sql.Timestamps, they have an extra nanos field. Calendar of course, knows nothing of nanos so will blindly ignore it and effectively drop it when creating the zeroedDate at the end, which you could then use to create a new Timetamp object.

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

I should also note that Calendar is not thread-safe, so don't go thinking you can make that a static single cal instance called from multiple threads to avoid creating new Calendar instances.

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

#2


18  

If you're using commons lang you can call DateUtils.truncate. Here's the javadoc documentation.

如果你正在使用commons lang,你可以调用DateUtils.truncate。这是javadoc文档。

It does the same thing @Alex Miller said to do.

它和@Alex Miller所做的一样。

#3


7  

Assuming your "timestamp" is a java.util.Date, which is represented as the number of milliseconds since the beginning of the epoch (Jan 1, 1970), you can perform the following arithmetic:

假设您的“timestamp”是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);
}

#4


4  

I prefer this solution:

我更喜欢这个解决方案

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

#5


3  

Do this

做这个

import org.apache.commons.lang.time.DateUtils;

Date myDate = new Date();
System.out.println(myDate);        
System.out.println(DateUtils.truncate(myDate, Calendar.DATE));

and the output is

而输出是

Wed Mar 19 14:16:47 PDT 2014
Wed Mar 19 00:00:00 PDT 2014

Wed Mar 19 14:16:47 PDT 2014 Wed Mar 19 00:00:00 PDT 2014

#6


1  

Since I don't do much DateTime manipulation, this might not be the best way to do it. I would spawn a Calendar and use the Date as source. Then set hours, minutes and seconds to 0 and convert back to Date. Would be nice to see a better way, though.

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

#7


0  

Using Calendar.set() would certanly be "by the book" solution, but you might also use java.sql.Date:

使用Calendar.set()可能是“书本”解决方案,但您也可以使用java.sql.Date:

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

That would do exactly what you want since:

这将完全符合您的要求,因为:

To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.

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

Since java.sql.Date extends java.util.Date, you can freely use it as such. Be aware that wantedDate.getTime() will retrieve original timestamp though - that's why you don't want to create another java.util.Date from java.sql.Date!

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

#8


0  

Find below a solution which employs Joda Time and supports time zones. So, you will obtain the current date and time (into currentDate and currentTime) or some date and time you inform (into informedDate and informedTime) in the currently configured timezone in the JVM.

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

The code below also informs if the informed date/time is in future (variable schedulable).

下面的代码还会通知未来的通知日期/时间(可变计划)。

Please notice that Joda Time does not support leap seconds. So, you can be some 26 or 27 seconds off the true value. This probably will only be solved in the next 50 years, when the accumulated error will be closer to 1 min and people will start to care about it.

请注意,Joda Time不支持闰秒。所以,你可以减去26或27秒的真实价值。这可能只会在未来50年内解决,届时积累的误差将接近1分钟,人们将开始关心它。

See also: https://en.wikipedia.org/wiki/Leap_second

另见: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;
    }
}

#9


0  

Here's a simple function with a main example:

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

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

#1


75  

You can go Date->Calendar->set->Date:

你可以去Date-> Calendar-> set-> 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

I love Java dates.

我喜欢Java约会。

Note that if you're using actual java.sql.Timestamps, they have an extra nanos field. Calendar of course, knows nothing of nanos so will blindly ignore it and effectively drop it when creating the zeroedDate at the end, which you could then use to create a new Timetamp object.

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

I should also note that Calendar is not thread-safe, so don't go thinking you can make that a static single cal instance called from multiple threads to avoid creating new Calendar instances.

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

#2


18  

If you're using commons lang you can call DateUtils.truncate. Here's the javadoc documentation.

如果你正在使用commons lang,你可以调用DateUtils.truncate。这是javadoc文档。

It does the same thing @Alex Miller said to do.

它和@Alex Miller所做的一样。

#3


7  

Assuming your "timestamp" is a java.util.Date, which is represented as the number of milliseconds since the beginning of the epoch (Jan 1, 1970), you can perform the following arithmetic:

假设您的“timestamp”是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);
}

#4


4  

I prefer this solution:

我更喜欢这个解决方案

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

#5


3  

Do this

做这个

import org.apache.commons.lang.time.DateUtils;

Date myDate = new Date();
System.out.println(myDate);        
System.out.println(DateUtils.truncate(myDate, Calendar.DATE));

and the output is

而输出是

Wed Mar 19 14:16:47 PDT 2014
Wed Mar 19 00:00:00 PDT 2014

Wed Mar 19 14:16:47 PDT 2014 Wed Mar 19 00:00:00 PDT 2014

#6


1  

Since I don't do much DateTime manipulation, this might not be the best way to do it. I would spawn a Calendar and use the Date as source. Then set hours, minutes and seconds to 0 and convert back to Date. Would be nice to see a better way, though.

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

#7


0  

Using Calendar.set() would certanly be "by the book" solution, but you might also use java.sql.Date:

使用Calendar.set()可能是“书本”解决方案,但您也可以使用java.sql.Date:

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

That would do exactly what you want since:

这将完全符合您的要求,因为:

To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.

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

Since java.sql.Date extends java.util.Date, you can freely use it as such. Be aware that wantedDate.getTime() will retrieve original timestamp though - that's why you don't want to create another java.util.Date from java.sql.Date!

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

#8


0  

Find below a solution which employs Joda Time and supports time zones. So, you will obtain the current date and time (into currentDate and currentTime) or some date and time you inform (into informedDate and informedTime) in the currently configured timezone in the JVM.

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

The code below also informs if the informed date/time is in future (variable schedulable).

下面的代码还会通知未来的通知日期/时间(可变计划)。

Please notice that Joda Time does not support leap seconds. So, you can be some 26 or 27 seconds off the true value. This probably will only be solved in the next 50 years, when the accumulated error will be closer to 1 min and people will start to care about it.

请注意,Joda Time不支持闰秒。所以,你可以减去26或27秒的真实价值。这可能只会在未来50年内解决,届时积累的误差将接近1分钟,人们将开始关心它。

See also: https://en.wikipedia.org/wiki/Leap_second

另见: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;
    }
}

#9


0  

Here's a simple function with a main example:

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

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