在Java中,给定时间戳,如何将时间部分单独重置为00:00:00,以便时间戳代表该特定日期的午夜?
在T-SQL中,此查询将实现相同的目标,但我不知道如何在Java中执行此操作。
SELECT CAST( FLOOR( CAST(GETDATE() AS FLOAT ) ) AS DATETIME) AS 'DateTimeAtMidnight';
答案 0 :(得分:75)
您可以进入日期 - >日历 - >设置 - >日期:
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实例。
答案 1 :(得分:18)
如果你使用公共语言,你可以致电DateUtils.truncate
。这是javadoc documentation。
@Alex Miller说过这样做。
答案 2 :(得分:7)
假设您的“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);
}
答案 3 :(得分:4)
我更喜欢这个解决方案:
GregorianCalendar now = new GregorianCalendar();
GregorianCalendar calendar = new GregorianCalendar(
now.get(GregorianCalendar.YEAR), now.get(GregorianCalendar.MONTH),
now.get(GregorianCalendar.DAY_OF_MONTH));
答案 4 :(得分:4)
这样做
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
答案 5 :(得分:1)
由于我没有做太多的DateTime操作,这可能不是最好的方法。我会生成一个日历并使用Date作为源。然后将小时,分钟和秒设置为0并转换回日期。不过,看到更好的方法会很高兴。
答案 6 :(得分: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!
答案 7 :(得分:0)
在下面找到一个采用Joda Time并支持时区的解决方案。
因此,您将获得当前日期和时间(进入currentDate
和currentTime
)或您在当前配置的时区中通知(进入informedDate
和informedTime
)的某个日期和时间在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;
}
}
答案 8 :(得分:0)
这是一个简单的函数,主要有一个例子:
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));
}
}
答案 9 :(得分:0)