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フィールドがあることに注意してください。カレンダーはもちろん、nanoを何も知らないので、最後にzeroedDateを作成するときにそれを盲目的に無視し、事実上それをドロップします。これを使用して、新しいTimetampオブジェクトを作成できます。
また、Calendarはスレッドセーフではないため、新しいCalendarインスタンスの作成を回避するために、複数のスレッドから呼び出される静的な単一calインスタンスを作成できるとは考えないでください。
Commons langを使用している場合は、DateUtils.truncate
。 javadoc documentation です。
@Alex Millerが言ったのと同じことをします。
「タイムスタンプ」がエポックの開始(1970年1月1日)からのミリ秒数として表されるJava.util.Dateであると仮定すると、次の算術演算を実行できます。
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);
}
これを行う
import org.Apache.commons.lang.time.DateUtils;
Date myDate = new Date();
System.out.println(myDate);
System.out.println(DateUtils.truncate(myDate, Calendar.DATE));
そして出力は
2014年3月19日水曜日14:16:47 PDT 2014
3月19日水曜日00:00:00 PDT 2014
私はこの解決策を好む:
GregorianCalendar now = new GregorianCalendar();
GregorianCalendar calendar = new GregorianCalendar(
now.get(GregorianCalendar.YEAR), now.get(GregorianCalendar.MONTH),
now.get(GregorianCalendar.DAY_OF_MONTH));
私はDateTime操作をあまりしないので、これはそれを行うための最良の方法ではないかもしれません。カレンダーを作成し、日付をソースとして使用します。次に、時間、分、秒を0に設定し、日付に戻します。しかし、より良い方法を見ることができればうれしいです。
Joda Timeを採用し、タイムゾーンをサポートするソリューションを以下に示します。したがって、現在の日付と時刻(currentDate
とcurrentTime
に)または通知する日付と時刻(informedDate
とinformedTime
に)を取得します。 JVMで現在構成されているタイムゾーン。
以下のコードは、通知された日付/時刻が将来のものであるかどうかも通知します(変数schedulable
)。
Joda Timeはうるう秒をサポートしていないことに注意してください。そのため、真の値から26または27秒遅れることがあります。これはおそらく、累積エラーが1分に近くなり、人々がそれを気にし始める次の50年以内に解決されるでしょう。
参照: 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;
}
}
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を拡張するため、そのように自由に使用できます。 wantedDate.getTime()は元のタイムスタンプを取得することに注意してください-だから、Java.sql.Dateから別のJava.util.Dateを作成したくないのです!
主な例を使用した単純な関数を次に示します。
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));
}
}